DOM 엘리먼트 선택

shleecloud·2021년 8월 8일
0

querySelector, querySelectorAll

querySelector
엘리먼트 하나만 반환. 조건을 만족하는 여러개일 경우 가장 처음 엘리먼트를 반환.

querySelectorAll
유사 배열 형태로 리턴함

getElementBy ~~~

getElementById
엘리먼트 하나만 반환

getElementsByTagName, getElementsByClassName (elements! s로 끝남)
유사 배열 객체로 반환

HTMLCollection

getElementsByClassName 메소드의 반환값은 HTMLCollection 이다. 이것은 반환값이 복수인 경우, HTMLElement의 리스트를 담아 반환하기 위한 객체로 배열과 비슷한 사용법을 가지고 있지만 배열은 아닌 유사배열(array-like object)이다. 또한 HTMLCollection은 실시간으로 Node의 상태 변경을 반영한다. (live HTMLCollection)

// HTMLCollection을 반환한다. HTMLCollection은 live하다.
const elems = document.getElementsByClassName('red');

for (let i = 0; i < elems.length; i++) {
  // 클래스 어트리뷰트의 값을 변경한다.
  elems[i].className = 'blue';
}

위 예제에서 iHTMLCollection, 실시간으로 변하는 배열의 인덱스를 가리킨다.
0번째 인덱스가 'red'로 변경되는 순간, getElementsByClass('red') 조건에서 벗어난다.
0번째 인덱스는 'red'가 아니므로 사라지고 1번 인덱스가 0번 인덱스 자리로 온다. 다음 실행은 이전에 2번 인덱스였던 요소가 실행된다.
그리고 i 값이 실시간으로 줄어드는 배열의 인덱스를 벗어나는 순간 에러를 발생시키고 종료된다.

해결 방법

  • 반복문을 역방향으로 돌린다.
  • while 반복문을 사용한다. 이때 elems에 요소가 남아 있지 않을 때까지 무한반복하기 위해 index는 0으로 고정시킨다.
  • HTMLCollection을 배열로 변경한다. 이 방법을 권장한다.
    [...elems].forEach(elem => elem.className = 'blue')
  • querySelectorAll 메소드를 사용하여 HTMLCollection(live)이 아닌 NodeList(non-live)를 반환하게 한다.

참조 URL : https://poiemaweb.com/js-dom#32-여러-개의-요소-노드-선택dom-query

profile
블로그 옮겼습니다. https://shlee.cloud

0개의 댓글