2. 요소 노드 취득
- HTML의 구조나 내용 또는 스타일 등을 동적으로 조작하려면 먼저 요소 노드를 취득해야 한다.
① id를 이용한 요소 노드 취득
- document.prototype.getElementById 메서드는 인수로 전달한 id값을 갖는 하나의 요소 노드를 탐색하여 반환한다.
- id값은 HTML 문서 내에서 유일한 값이여야 하며, class 어트리뷰트와 달리 공백 문자로 구분하여 여러개의 값을 가질 수 없다.
- getElementById 메서드는 인수로 전달된 id값을 갖는 첫 번째 요소 노드만 반환한다. → id값이 중복되어도 첫 번째 id값만 반환한다.
- 인수로 전달된 id값을 갖는 HTML 요소가 존재하지 않는 경우 getElementById 메서드는 null을 반환한다.
<!DOCTYPE html>
<html>
<body>
<ul>
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
<script>
const $banana = document.getElementById('banana');
$banana.style.color = 'yellow';
const $grape = document.getElementById('grape');
$grape.style.color = 'purple';
</script>
</body>
</html>
② 태그 이름을 이용한 요소 노드 취득
- document.prototype/Element.prototype.getElementsByTagName 메서드는 인수로 전달한 태그 이름을 갖는 모든 요소 노드들을 탐색하여 반환한다.
- 함수는 하나의 값만 반환할 수 있으므로 여러 개의 값을 반환하려면 배열이나 객체와 같은 자료구조에 담아 반환해야 한다.
- getElementsByTagName 메서드가 반환하는 DOM 컬렉션 객체인 HTMLCollection 객체는 유사 배열 객체이면서 이터러블이다.
- 인수로 전달된 태그 이름을 갖는 요소가 존재하지 않는 경우 getElementsByTagName 메서드는 빈 HTMLCollection객체를 반환한다.
<!DOCTYPE html>
<html>
<body>
<ul>
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
<script>
const $li = document.getElementsByTagName("li");
[...$li].forEach( element => { element.style.color = "red"; });
</script>
</body>
</html>
③ Class를 이용한 요소 노드 취득
- Document.prototype/Element.prototype.getElementsByClassName 메서드는 인수로 전달한 class 어트리뷰트 값(=class값)을 갖는 모든 요소 노드들을 탐색하여 반환한다.
- getElementsByClassName 메서드는 여러 개의 요소 노드 객체를 갖는 DOM 컬렉션 객체인 HTMLCollection 객체를 반환한다.
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<ul>
<li id="fruit apple">사과</li>
<li id="fruit banana">바나나</li>
<li id="fruit orange">오렌지</li>
</ul>
<script>
const $fruits = document.getElementsByClassName("fruit");
[...$fruits].forEach( element => { element.style.color = "red"; });
const $apples = document.getElementsByClassName("fruit apple");
[...$apples].forEach( element => { element.style.color = "blue"; });
</script>
</body>
</html>
④ CSS 선택자를 이용한 요소 노드 취득
- CSS 선택자(selector)는 스타일을 적용하고자 하는 HTML 요소를 특정할 때 사용하는 문법이다.
1. Document.prototype/Element.prototype.querySelector 메서드
- 인수로 전달한 CSS 선택자를 만족시키는 하나의 요소 노드를 탐색하여 반환한다.
- 인수로 전달한 CSS 선택자를 만족시키는 요소 노드가 여러개인 경우 첫 번째 요소 노드만 반환한다.
- 인수로 전달된 CSS 선택자를 만족시키는 요소 노드가 존재하지 않는 경우 null을 반환한다.
2. Document.prototype/Element.prototype.querySelectorAll 메서드
- 인수로 전달한 CSS 선택자를 만족 시키는 모든 요소 노드를 탐색하여 반환한다.
- querySelectorAll 메서드는 여러 개의 요소 노드 객체를 갖는 DOM 컬렉션 객체인 NodeList 객체를 반환한다.
- 인수로 전달된 CSS 선택자를 만족시키는 요소 노드가 존재하지 않는 경우 NodeList 객체를 반환한다.
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<ul>
<li id="apple">사과</li>
<li id="banana">바나나</li>
<li id="orange">오렌지</li>
</ul>
<script>
const $fruit = document.querySelector(".banana");
const $fruits = document.querySelector("ul > li");
console.log("$fruits");
$fruits.forEach( element => { element.style.color = "red"; });
</script>
</body>
</html>
④-1 특정 요소 노드를 취득할 수 있는지 확인
- Element.prototype.matches 메서드는 인수로 전달한 CSS 선택자를 통해 특정 요소 노드를 취득할 수 있는지 확인한다.
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<ul>
<div class="fruits">
<li id="apple">사과</li>
<li id="banana">바나나</li>
<li id="orange">오렌지</li>
</div>
</ul>
<script>
const $apple = document.querySelector(".apple");
console.log($apple.matches("#fruits > li.apple"));
console.log($apple.matches("#fruits > li.banana"));
</script>
</body>
</html>
⑤ HTMLCollection과 NodeList
- DOM 컬렉션 객체인 HTMLCollection과 NodeList는 DOM API가 여러 개의 결과값을 반환하기 위한 DOM컬렉션 객체다.
- HTMLCollection과 NodeList는 모두 유사 배열 객체이면서 이터러블이기 때문에 for...of문으로 순회할 수 있으며 스프레드 문법을 사용하여 간단히 배열로 반환할 수 있다.
- HTMLCollection과 NodeList는 노드 객체의 상태 변화를 실시간으로 반영하는 살아있는 객체다. ( HTMLCollection은 항상 live 객체이지만 NodeList는 특정상황에만 live 객체로 동작한다.)
- 노드 객체의 상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하려면 HTMLCollection 이나 NodeList 객체를 배열로 반환하여 사용하는 것을 권장한다.
1. HTMLCollection
- getElementsByTagName, getElementsByClassName 메서드가 반환하는 HTMLCollection 객체는 노드 객체의 상태 변화를 실시간으로 반영하는 살아 있는(live) DOM 컬렉션 객체다.
- HTMLCollection 객체를 살아있는 객체라고 부르기도 한다.
2. NodeList
- HTMLCollection 객체의 부작용을 해결하기 위해 querySelectorAll 메서드를 사용한다.
- querySelectorAll 메서드는 DOM 컬렉션 객체인 NodeList 객체를 반환한다.
- NodeList 객체는 실시간으로 노드 객체의 상태 변경을 반영하지 않는(non-live) 객체다.
- NodeList 객체는 대부분의 경우 노드 객체의 상태 변경을 실시간으로 반영하지 않고 과거의 정적 상태를 유지하는 non-live 객체로 동작하지만 childNodes 프로퍼티가 반환하는 NodeList 객체는 HTMLCollection 객체와 같이 실시간으로 노드 객체의 상태 변경을 반영하는 live 객체로 동작하므로 주의가 필요하다.