객체를 불러오기 위해 사용하는 getElementsByClassName과 querySelectorAll의 차이를 간단히 요약하면,
1. getElementsByClassName(그리고, getElementsByTagName)은 HTMLCollection을 반환하고,
2. querySelectorAll은 NodeList를 반환한다.
3. 일반적으로, getElementsByClassName이 더 빠르다고 한다.
우선 자바스크립트에서 객체에 접근하는 방법을 알아보자.
1. getElementById("id")
→ id 값이 "id"인 첫번째 객체를 리턴한다.
2. getElementsByTagName("div")
→ 태그 이름이 "div"인 모든 DOM 객체들을 찾아 컬렉션 리턴한다.
3. getElementsByClassName("apple")
→ class 값이 "apple"인 모든 DOM 객체들을 찾아 컬렉션 리턴한다.
4. querySelector(selectors)
→ getElements...와 달리 특정 name, id, class를 제한하지 않고 css선택자를 사용하여 요소를 찾는다.
querySelector는 해당 선택자와 일치하는 첫번째 객체를 리턴한다.
사용 예시는 다음과 같다.
document.querySelector("div") // 태그 이름이 div인 객체를 찾는다.
document.querySelector(".apple") // class 값이 apple인 객체를 찾는다.
document.querySelector("#id") // id 값이 id인 객체를 찾는다.
5. querySelectorAll(selectors)
→ querySelector와 달리, 조건에 맞는 웹 문서 내의 모든 객체를 찾아 리턴한다.
일반적으로 사용할때는, getElementsByClassName, getElementsByTagName과 querySelectorAll의 차이를 찾기 어려워 보이지만 각각 HTMLCollection과 NodeList를 반환한다는 차이가 있다.
먼저, HTMLCollection과 NodeList는 모두 *유사 배열으로, length 프로퍼티를 가지므로 배열처럼 접근할 수 있다.
( * 유사 배열은 length 프로퍼티가 있어 배열처럼 사용할 수 있지만, Array의 메서드를 사용할 수 없다.)
두 유사배열의 차이점을 살펴보면,
HTMLCollection은 Live DOM 컬렉션 객체로, 내부 원소(노드)에 변화가 생기면 이를 즉시 반영한다.
NodeList는 Non-Live DOM 컬렉션 객체로, 원소(노드)의 변화를 즉시 반영하지 않는다.
Live와 Non-Live의 차이를 쉽게 이해하기 위해서 예시를 하나 살펴보자.
<!DOCTYPE html>
<html>
<head>
<style>
.red {
font-weight : bold;
color: red;
}
.green {
color: green;
}
</style>
</head>
<body>
<ul>
<li class="red">Samsung</li>
<li class="red">LG</li>
<li class="red">Apple</li>
</ul>
<script>
let companies = document.getElementsByClassName("red");
for (let i = 0; i < companies.length; i++) {
companies[i].className = "green";
}
</script>
</body>
</html>
[실행결과]
의도와 다르게 실행 결과, 2번째와 4번째 값이 변하지 않은 것을 확인 할 수 있다.
이것이 바로 HTMLCollection이 Live 객체이기 때문에 일어난 현상이다.
반복문에서 i=0일때 companies[0]의 class 값이 바뀌면서, companies의 내부 원소에 변화가 생긴다.
따라서, companies는 즉시 변화를 반영하여 다음 값이었던 companies[1]가 companies[0]으로 바뀐다.
그리하여 companies[1]의 값은 "LG"가 아닌 "Apple"이 된 것이다.
Non-Live 객체인 NodeList의 경우는 이와 같은 현상이 발생하지 않는다.
메서드의 사용면에서는 다음과 같은 차이가 있다.
HTMLCollection은 .item이나 .namedItem 메서드가 사용 가능하지만, .forEach나 .map같은 메소드가 사용 불가능하며,
NodeList는 .item과 .forEach 메소드 등이 사용 가능하지만 .map이나 .filter 등의 메소드가 사용 불가능하다.
NodeList와 HTMLCollection을 일반 배열과 동일하게 사용하기 위해서는 Array.from 메소드를 사용하면 된다.
사용 방법은 다음과 같다.
let companies = document.querySelectorAll('.red')
let companiesArr = Array.from(companies)
위와 같이 하면 일반 배열과 동일하게 사용가능하다.
'WEB > 💡 Javascript' 카테고리의 다른 글
[Javascript] 역따옴표(백틱)을 이용한 템플릿 리터럴(template literal) (0) | 2022.07.27 |
---|---|
[Javascript] '=='와 '==='의 차이점 (0) | 2022.07.27 |
[Javascript] 아코디언 메뉴 만들기 (접기/펼치기 기능 구현) (0) | 2022.07.20 |
[Javascript] DOMContentLoaded와 onload의 차이 (0) | 2022.07.14 |
[Javascript] setTimeout을 setInterval처럼 주기적으로 불러오기 (0) | 2022.06.16 |