HTML의 구조나 내용 또는 스타일 등을 동적으로 조작할 필요가 자주 있는데, 이를 위해서는 먼저 요소 노드를 취득해야 한다.
같은 class 어트리뷰트 값을 갖는 모든 요소 노드들을 취득하기 위한 방법에는 두 가지가 있는데, querySelectorAll
과 getElementsByClassName
이 바로 그것이다.
그런데 둘 다 같은 효과를 내는 것 같은데, 왜 두 개나 있는지 의문이 들었고 둘의 공통점과 차이점이 궁금해졌다. 특히, 습관적으로 Array.from()을 하여 유사배열객체를 배열로 만들어 왔는데 그 이유도 확실히 알아야겠다는 생각이 들었다.
for ...of
문으로 순회할 수 있다.Array.from
메서드나 스프레드 연산자
를 사용하여 배열로 만들 수 있다.item()
메서드는 두 객체에 모두 있는 메서드다. 첫 번째 인자로 받는 index 값에 해당하는 아이템을 반환한다.getElementsByTagName
, getElementsByClassName
메서드를 통해 반환된다.children
프로퍼티를 통해 반환된다.for 문을 역방향으로 순회
하거나 while 문을 사용하여 객체에 노드 객체가 남아 있지 않을 때까지 무한 반복하는 방법등으로 회피
할 수도 있다.HTMLCollection
객체를 사용하지 않고, 배열로 변환하는 것이다. 그러면 유용한 배열의 고차함수(forEach, map, filter, reduce 등)을 사용할 수 있다. 또는 querySelectorAll
메서드를 사용하여 NodeList
객체를 반환받아 사용할 수도 있다..[속성명]
의 방식으로 접근할 수도 있다.namedItem()
가 있다. 요소의 name
어트리뷰트의 값이 있는 경우에 이 메서드를 이용하여, namedItem()
의 첫 번째 인자가 name
어트리뷰트의 값과 일치하는 요소를 반환한다.querySelectorAll
메서드를 통해 반환된다.childNodes
프로퍼티를 통해 반환된다.childNodes
프로퍼티는 live 객체이므로 주의가 필요하다.이처럼 HTMLCollection이나 NodeList 객체는 예상과 다르게 동작할 때가 있어 다루기 까다롭고 실수할 수 있다. 또한, 각 객체마다 메서드를 어느 정도 제공하기는 하지만, 배열
의 고차함수(forEach, map, filter, reduce 등)만큼 다양한 기능을 제공하진 않는다.
그러므로 노드 객체의 상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하고 유용한 고차함수를 사용하려면, HTMLCollection이나 NodeList 객체를 배열
로 변환하여 사용하는 것이 좋다.
Array.from 메서드
나 스프레드 연산자
를 사용하여 간단히 배열로 변환할 수 있다.