자바스크립트로 프로젝트 진행할 때 알아두면 좋은 왕기초지식

SUSU·2022년 4월 18일
2

나는 코딩을 배운지 얼마 안 된 사람이라 바닐라 자바스크립트로 코드를 짤 때 모르는 것 투성이였다. 여기에 써있는 것들은 내가 부트캠프 과제 대부분에서 써서 왕기초지식이라는 이름으로 정리를 해본다.

자바스크립트 코드 시작?

즉시실행함수(IIFE,Immediately Invoked Function Expression)

(function(){
//코드
})();

이런 형식으로 생긴 함수로 자바스크립트 코드가 감싸져있는 것을 자주 볼 수 있다. 이것은 말 그대로 이 안에 들어있는 코드를 바로 실행해라라는 뜻이다.

즉시실행함수 참고사이트
https://findawayer.tistory.com/entry/IIE%EC%9D%98-%EC%9D%98%EB%AF%B8%EB%8A%94

근데 굳이 저 함수로 감싸지 않아도 코드들은 바로 실행될텐데 왜 감싼걸까?

전역객체를 보호하기 위해서이다.

자바스크립트의 장점(?)이면서 단점인 전역변수는 지양하는 것이 좋기 때문에 최소한으로 써야하는데, 이 즉시실행함수를 쓰면 함수 내에서 쓴 것들이 전역변수, 전역 함수가 되지 않는다.(이 함수 없이 그냥 쓴다면 다 전역변수, 전역함수가 되어버리는거다.)

이거에 관해서는 네임스페이스패턴이라는 것을 알아두면 좋다. 네임스페이스패턴이란 전역을 피하는 코딩기법으로 전역 객체를 하나만 만들고, 모든 기능을 이 객체에 추가하는 패턴이다.

네임스페이스패턴 참고사이트
https://mingule.tistory.com/51

init()

같은 의미로 init도 많이 쓰인다. 대신 init()은 전역객체 보호뿐 아니라 가독성을 위해 많이 쓴다. 최초로 실행되는 함수들을 여기다 넣어두고 실행시키면 모듈화할 때 편하기 때문이다.

함수

코드에서 쓰이는 함수들은 대게 하나의 행동만 하도록 짜는 것이 국룰이다. 여러가지 행동을 하는 함수로 짠다면, 오류가 났을 때 어떤 행동을 하다가 오류가 난건지 잡기 어렵다. 게다가 함수명 정하기 힘들다. 개발을 하면서 왜 개발자들이 코드 짜는 시간보다 변수명, 함수명 짜는 데 시간이 더 오래걸린다고 했는지 약간은 체감하는 중이다. 한 가지의 일을 한다면 그 일에 대한 걸로 함수명을 짜면 되는데, 여러가지 일을 한다면 그걸 대표할 함수명을 생각해야하기 때문에 머리가 많이 복잡해질 것이다.

깔끔한 함수 참고사이트
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kira4195&logNo=221230626334

HTML과 커뮤니케이션할 수 있는 자바스크립트 코드

<태그> 선택하기

일단 HTML에서 짜놓은 태그들을 선택할 수 있어야 그 태그들한테 어떻게 행동해라라고 명령을 할 수 있다. 선택할 수 있는 방법은 많다.

가장 기본적인 선택 방법으로는

document.getElementById()
document.getElementByClassName()

이 두 가지가 있다. 각자 id와 class명을 괄호안에 넣으면 선택이 된다. 하지만 뭐랄까 JQuery에서 $()처럼 한번에 태그들을 선택할 수 있으면 좋을텐데라는 생각을 한다면

document.querySelector()
document.querySelectorAll()

이것들을 사용하면 된다. querySelector이기 때문에 괄호 안에 클래스명이면 '.클래스명' Id이면 '#아이디명' 이렇게 넣어줘야한다. 나는 이것을 더 자주 사용하는 편이다. 하나하나 다 저렇게 쓰면 귀찮기 때문에 함수로 정해놓고 쓴다.

const get = (target) => document.querySelector(target);
const getAll = (target) => document.querySelectorAll(target);

함수로 한번 만들어 놓으면 나중에 get('.color-white') 이렇게만 쓰면되서 편하다.

querySelector를 쓸 때 주의해야할 것은 조건에 맞는 가장 처음에 있는 태그 하나만 선택이 된다. 전부가 필요하면 querySelectorAll을 쓰면 되지만 만약에 클릭이벤트를 이용해서 여러 태그들을 선택하고 싶을 땐 어떻게 해야할까?

내가 쓴 방법은 이렇다.

get('.부모요소').addEventListener('click', (e) => {e.target.classList.add("클래스명");});

클릭이벤트 자체는 부모요소로 걸어놓고 그 부모요소 안에 있는 target에게 행동을 명령한다. 더 좋은 방법이 있을 수 있으나 현재까지 나로서는 이런 방법을 이용하고 있다.

<태그>의 클래스 조절하기

위에서 예시로 든 classList를 이용해서 태그의 css를 수정할 수 있다. element.className 통해 엘리먼트의 클래스 목록에 접근하는 방식을 대체하는 간편한 방법이다. css파일에 호버할 때, 클릭했을 때 쓰이는 스타일들을 클래스로 만들어 뒀다가 해당 이벤트가 발생했을 때 추가하도록 하는 것이 저 Element.classList.add()이다. 클래스를 조절하는 것이기 때문에 querySelector같이 클래스명 앞에 '.'이 필요하진 않고 괄호안에 '클래스명'만 넣어주면 된다.

클래스를 조절하는 메서드에는 다양한 것들이 있다.

  • add 해당 클래스를 추가한다. 이미 있다면 무시한다.
  • remove 해당 클래스를 삭제한다. 해당 클래스가 없을 때 사용해도 오류가 나지 않는다.
  • toggle 해당 클래스가 있다면 삭제하고, 없다면 추가한다.
  • contains 해당 클래스가 있는지 확인한다.
  • item 콜렉션의 인덱스를 이용하여 클래스 값을 반환한다. 이 메서드는 클래스명이 아니라 인덱스 넘버를 받는다.
  • replace (대체될 클래스, 대체할 클래스)순으로 괄호 안을 작성하게 되면 두 개가 교체가 된다.

remove 메서드는 하나만 사용하기도 하지만 나는 JQuery의 empty() 같은 느낌으로 사용하기도 한다.

const getAll = (target) => document.querySelectorAll(target);
const array = [...getAll(target)]

for(let i = 0; i < array.length; i++) {
	array[i].classList.remeve('class');
}

이렇게 쓰면 어떤 클래스명을 가진 target들에게서 클래스를 모두 지울 수 있다. 만약 바로 getAll(target)을 element로 잡는다면 실행이 되지 않는다. 조절하는 element는 하나여야한다.

classList 참고사이트
https://developer.mozilla.org/ko/docs/Web/API/Element/classList

<태그> 생성하기

Html 바로 넣기

선택한 태그 안에 직접적으로 html요소를 써서 태그를 생성할 수 있다.
그걸 가능하게 해주는 메서드가 element.innerHTML이다.
이 메서드를 사용하면 html파일에서 쓰듯이 그대로 쓰면 태그를 생성해준다.

const text = 'hello world!'
querySelector('.class').innerHTML='<div class="test-text">' + text + '<div>';

물론 변수 text에 담은 내용을 그대로 써도 된다.

그런데 mdn에서 element.innerHTML을 설명할 때 요소의 내용을 수정할 때만 쓰고, 내용을 삽입할 때는 element.insertAdjacentHTML()을 사용하라고 한다. 왜일까?

요소(element)의 자손의 HTML 직렬화를 포함하는 DOMString 입니다. Setting the value of innerHTML 의 값을 설정(대입)하면 요소의 모든 자손이 제거되고, 문자열 htmlString에 지정된 HTML을 파싱하고, 생성된 노드로 대체합니다.

이 말은 요소 안에 있는 내용이 다 사라지고 내가 작성한 내용이 새롭게 재작성된다는 뜻이다. 그래서 아무 내용도 없던 요소면 괜찮지만 내용이 있던 요소라면 element.innerHTML 대신에 element.insertAdjacentHTML()를 이용하자.

참고사이트
https://developer.mozilla.org/ko/docs/Web/API/Element/innerHTML

문서객체 생성

많은 태그들을 코드로 써야한다면 element.innerHTML 혹은 element.insertAdjacentHTML()을 쓰겠지만 몇몇개의 코드를 쓴다면 element.createElement를 쓰는 것도 좋다. 요소를 직접 생성하여 setAttribute를 통해 클래스나, 아이디를 생성하고, appendChild를 이용하여 선택한 태그의 자식요소로 삽입할 수 있다. element.createElement가 아니더라도 element.innerHTML에 썼던 태그의 attribute를 수정하고 싶을 때 setAttribute이용해서 바꾸면 된다.

const box = document.creatElement('div')
box.setAttribute('class','box1')
querySelector('.부모요소').appendChild(box)

createElement 참고사이트
https://developer.mozilla.org/ko/docs/Web/API/Document/createElement
setAttribute 참고사이트
https://www.codingfactory.net/10419
appendChild 참고사이트
https://developer.mozilla.org/ko/docs/Web/API/Node/appendChild

텍스트 넣기

만약 태그를 만든 뒤 그 안에 텍스트를 수정하고 싶다면 어떻게 해야할까? element.innerHTML로 내용을 수정해야할까? 사실 element.innerHTML는 기존 내용을 한번 리셋한다는 위험부담이 있기때문에 단순 텍스트 수정을 위해서는 쓰지 않는게 좋다. 그럴 때 쓸 수 있는 것이 HTMLElement.innerText 이다.

querySelector('.class').innerText='hello world!'

inner로 시작해서인지 innerTextinnerHTML과 차이점을 묻는 글들도 많았다.
한 마디로 정리하면 innerText는 쓰는 그대로가 렌더되고, innerHTML은 태그 영역을 인식하여 태그 안에 있는 내용을 보여준다.

또한 innerTexttextContent도 비교할 수 있다. 단순 텍스트라면 모를까, 만약 태그로 만들어진 내용을 변수에 담아서 innerTexttextContent에 넣는다면 차이가 극명하게 나타난다. innerText는 담겨진 내용의 태그들도 이해하고 스타일도 인식하지만 textContent는 무식하게 다 텍스트로 렌더링해버린다.

innerText와 textContent 예시
https://developer.mozilla.org/ko/docs/Web/API/HTMLElement/innerText

태그에 이벤트 걸기

element.addEventListener()을 이용해서 태그에 이벤트를 걸 수 있다. 괄호 안에는 이벤트의 종류, 이벤트 발생시 동작할 함수가 들어가면 된다. 복잡한 일을 한다면 미리 함수를 작성해서 호출하면 되지만, 만약 단순한 일을 한다면 화살표 함수를 이용해서 바로 함수를 실행시켜도 된다.

이벤트의 종류는 다양하기 때문에 아래 사이트를 참고하길 바란다.
https://developer.mozilla.org/ko/docs/Web/Events

profile
프론트엔드 개발을 이제 막 처음하는 신선한 개발자

0개의 댓글