노드 취득
- 프론트엔드 개발자의 관점에서 HTML 태그 는 단순 태그를 넘어서 자바스크립트 객체의 관점으로 보아야 한다.
- DOM 에 접근할 수 있는 DOM API의 종류
| API | 설명 |
| getElementById | 태그의 id 속성을 이용하여 노드를 선택한다. |
| getElementsByClassName | 태그의 class 속성을 이용하여 노드를 선택한다. HTMLCollection 유사 배열객체 를 리턴 |
| getElementsByTagName | 태그의 이름을 이용하여 노드를 선택한다. HTMLCollection 유사 배열객체 를 리턴 |
| querySelector | CSS 선택자를 사용하여 노드를 선택한다. |
| querySelectorAll | CSS 선택자를 사용하여 여러 노드를 선택한다. NodeList 유사 배열객체를 리턴 |
getElementById
document.getElementById( id );
- id 값을 이용하여 노드를 선택한다.
- 같은 id 를 갖는 여러 태그가 있을경우 첫 번째 노드만 반환하고, id 값을 가진 태그가 없는 경우 null 을 리턴한다.
- id 값과 동일한 이름의 전역변수가 암묵적으로 선언되고 동일한 이름의 전역변수가 존재할 경우 노드 객채가 할당되지 않는다.
<body>
<ul>
<li id="red">red</li>
<li id="blue">blue</li>
</ul>
<script>
const $red = document.getElementById("red");
const $blue = document.getElementById("blue");
console.log($red); // li#red
console.log($blue); // li#blue
</script>
</body>
getElementsByClassName
document.getElementsByClassName( class );
- class 를 사용하여 노드를 선택한다.
- HTMLCollection 는 여러 노드 객체를 가지고 있는 유사 배열 객체를 리턴한다.
<body>
<ul>
<li class="list">red</li>
<li class="list">blue</li>
</ul>
<script>
const $lists = document.getElementsByClassName("list");
console.log($lists); // HTMLCollection(2) [li.list, li.list]
</script>
</body>
getElementsByTagName
document.getElementsByTagName( div )
- tag 이름을 기준으로 노드를 선택한다.
<body>
<ul>
<li class="list">red</li>
<li class="list">blue</li>
</ul>
<script>
const $li = document.getElementsByTagName("li");
console.log($lis); // HTMLCollection(2) [li.list, li.list]
</script>
</body>
querySelector & querySelectorAll
document.querySelector( );
document.querySelectorAll( );
- CSS 의 선택자 방식을 사용해서 노드를 선택하는 방법으로 복잡하거나 정교한 노드 선택 이 가능하다.
- querySelectorAll 을 사용하여 노드를 선택할경우 NodeList 라는 유사 배열 객체를 리턴한다.
- 기존의 태그 아이디, 클래스 의 이름을 찾아 노드를 선택하는 메소드보다 querySelector 가 속도면에선 느리다.
<body>
<div id="user" class="box">
<p class="name">이름 : 혜성</p>
<p class="age">나이 : 27</p>
<input type="text" />
</div>
<script>
const $user = document.querySelector("#user"); // div#user.box
const $box = document.querySelector(".box"); // div#user.box
const $p = document.querySelectorAll("p"); // NodeList(2) [p.name, p.age]
const $name = document.querySelector("#user > .name"); // p.name
const $age = document.querySelector(".box > .age"); // p.age
const $input = document.querySelector("input[type='text']"); // <input type="text">
</script>
</body>
HTMLCollection, NodeList 🔥
getElementsByClassName 를 사용했을때 리턴하는 HTMLCollection 객체와 querySelector 가 리턴하는 NodeList 객체모두 배열이아닌 유사 배열 객체이다.
두 객체의 특징은 ( live ) 상태를 실시간으로 반영한다.
NodeList 는 대부분 non-live 형태로 동작하나 일부는 live 한 상태로 존재한다.
그렇다면 이 살아있다는 상태, 실시간으로 상태변화를 감지한다는것은 무슨 의미를 갖는가?
<head>
<style>
.red {
color: red;
}
.blue {
color: blue;
}
</style>
</head>
<body>
<ul>
<li class="red">a</li>
<li class="red">b</li>
<li class="red">c</li>
</ul>
<script>
const $elem = document.getElementsByClassName("red");
for (let i = 0; i < $elem.length; i++) {
$elem[i].className = "blue";
}
</script>
</body>
</html>
위의 코드의 결과 값은 아래 이미지와 같다.

결과를 기대하기에 모든 li 태그는 blue 로 변경되길 원했으나 동작이 이상하게 작동했다.
이유는 HTMLCollection가 실시간으로 감지하여 첫번째 노드의 클래스를 blue 변경 한 순간 $elem.length 의 길이가 2로 변했고,
두번째 순회 상태일때 ( i = 1 일때 ) 3번째 변경되길 원했던 li 노드가 먼저 변경되어버린다.
따라서 HTMLCollection 바로 순회에 사용하는 것에는 주의가 필요하다.
이러한 부작용을 제거하기 위해선 해당 유사 배열 객체들을 배열 객체로 변환하여 사용한다.
[...$elem].forEach(elem => elem.className = "blue"); // 첫번째 방법
Array.from($elem).forEach(elem => elem.className = "blue"); // 두번째 방법
Reference
- 모던 자바스크립트 (이웅모)
There might be incorrect information or outdated content.
'Web > Javascript' 카테고리의 다른 글
| [JAVASCRIPT] DOM - 노드 조작 (0) | 2023.08.04 |
|---|---|
| [JAVASCRIPT] DOM - 노드 탐색 (0) | 2023.08.04 |
| [JAVASCRIPT] Full Screen (0) | 2023.07.29 |
| [JAVASCRIPT] STRING (0) | 2023.07.29 |
| [JAVASCRIPT] ARRAY (0) | 2023.07.28 |