자바스크립트

querySelectorAll 와 getElementsByClassName의 차이

jdy8739 2021. 12. 22. 00:11
const cards = document.querySelectorAll('.card');
const cards = document.getElementsByClassName('card');
 

단순히 이벤트리스너를 달기위해 선택자로 저 함수를 사용할때는 몰랐는데,

 

저 함수들은 각각 다른 형태의 객체를 반환한다.

 

querySelectorAll는 NodeList를 반환하고,

 

getElementsByClassName는 HTMLCollection을 반환한다.

 

둘의 공통점은 유사배열이라는것!

 

어쨋든 두 자료형은 iterable로써 열거 가능한 속성을 갖는데

 

따라서 for 문 등으로 인덱스별 순환이 가능하다.

 

하지만 두 자료형을 직접적으로 조작해 dom을 바꿔주려하면 개발자의 의도대로 잘 동작하지않을 수 있다.

 

 

이는 역시 유사배열의 속성때문인데,

 

HTMLCollection은 live한 객체, 즉, 살아있는 객체라하여 getElement 선택자로 특정 element들의

 

HTMLCollection 배열을 얻었다고 가정한다.

 

이 배열을 얻은 기준이 특정 class명이라고할 때, 이 HTMLCollection 배열의 class이름을 for문으로 순회하며 바꿔준다면

 

이 HTMLCollection 배열은 live한 객체로서 수정사항이 실시간으로 반영이되기때문에,

 

기존에 선택자로 추출된 HTMLCollection 배열의 길이에서 수정이 될때마다 length가 실시간으로 1씩 줄어든다.

 

따라서 개발자의 의도대로 쉽게 다룰 수 없다.

 

 

NodeList는 반면 Non-live한 객체로써 위의 상황은 일어나지않지만,

 

만약 특정 요소의 childNodes함수로 추출된 NodeList 배열이라면 

 

같은 현상이 일어난다고한다.

 

 

따라서 저 두 자료형을 순환해야하는 로직을 사용해야한다면

 

Array.from( ) 함수로 정식 배열로 바꿔주는 절차를 거치는것이 권장된다.

 

또한 유사배열은 forEach 등의 함수를 사용할 수 없으므로

 

Array.from(식별자).forEach( callbackFunction);

 

요런식으로 쓸수있는 객체 배열 형식으로 변환을 해줘야한다.