DOM은 HTML 문서의 계층적 구조와 정보를 표현
하며 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리 자료 구조
이며 트리 자료 구조는 노드들의 계층구조(parent-child)로 구성되어 노드 간의 계층적 구조(부자, 형제 관계)를 표현하는 비선형 자료구조
를 말한다. 선형 자료구조에는 배열, 스택, 큐, 해시 테이블 등이 있다.
루트 노드(root node)
: 트리 자료 구조의 최상위 노드로 부모 노드가 없으며 0개 이상의 자식 노드를 갖는다.
리프 노드(leaf node)
: 자식 노드가 없는 노드를 지칭할 때 부른다.
그 외
: 부모 노드, 자식 노드, 형제 노드 등이 있는데 이것은 트리 자료 구조의 계층 구조에 따라 얼마든지 다르게 부를 수 있다.
노드의 객체 타입은 12가지이며 그 중 중요한 노드 타입 4가지는 다음과 같다.
문서 노드
: DOM 트리의 최상위에 존재하는 루트 노드
로서 document 객체를 가리킨다. HTML문서 전체를 가리키는 객체로 전역 객체 window의 document 프로퍼티에 바인딩되어 있다. 문서노드는 window.document 혹은 document로 참조할 수 있다.
요소 노드
: HTML 요소 각각을 가리키는 노드이다.
어트리뷰트 노드
: HTML 요소의 어트리뷰트를 가리키는 객체
이다. 해당 노드는 어트리뷰트가 지정된 HTML 요소 노드에만 연결되어 있어 부모 노드가 없다. 즉, 요소 노드의 부모를 어트리뷰트 노드가 갖지 않으므로 요소 노드와 형제 관계는 아니다. 따라서 어트리뷰트 노드를 조작하기 위해서는 연결된 요소 노드에 먼저 접근해야 한다.
텍스트 노드
: HTML 요소의 텍스트를 가리키는 객체
이다. 요소 노드는 문서의 구조를 표현하는 반면 텍스트 노드는 문서의 정보를 나타낸다.
텍스트 노드는 요소 노드의 자식 노드로 텍스트 노드에 접근하기 위해서는 부모 노드인 요소 노드에 먼저 접근해야 한다.
DOM을 구성하는 노드 객체는 자신의 구조와 정보를 제어할 수 있는 DOM API를 사용할 수 있고 이를 통해 노드 객체는 다른 노드를 탐색하거나 본인 자신을 조작할 수도 있게 된다.
노드 객체는 브라우저 환경에서 추가로 제공하는 호스트 객체로, 자바 스크립트 객체의 종류로써 프로토 타입에 의한 상속 구조를 갖는다. 이러한 상속 속성으로 인해 각 요소는 프로토 타입 체인에 있는 모든 프로토 타입의 프로퍼티나 메서드를 상속받아 사용할 수 있게된다.
노드 객체는 종류와 상관없이 모든 노드 객체가 공통으로 갖는 기능도 있고 노드 타입에 따라 다른 고유의 기능도 있는다. 공통으로 갖는 기능은 프로토 타입 체인의 상위에 고유의 기능은 하위에 구축되어 있다.
예시 ) button property and method
+ properties: innerHTML, style, firstChild, etc.
+ method: click(), appendChild(), setAttribute(), etc.
요소 노드를 취득하는 방법은 여러가지가 있지만 일반적으로 선택자 문법을 사용하여 노드 요소를 취득하는 것이 그 외의 방법보다 다소 느리다고 알려져 있다. 하지만 선택자를 사용하면 좀 더 구체적이고 일관된 방식으로 요소 노드를 취득할 수 있다
는 점에서 id 어트리뷰트가 있는 요소 노드를 취득하는 것이 아니라면 선택자을 통해 요소 노드를 취득하는 것을 권장
한다.
getElementsByTagName / getElementsByClassName
: 조건에 맞는 요소를 전부 검색하여 HTML Collection형 태로 반환한다. Document.prototype과 Element.prototype에 정의된 메서드가 각각 있다.
HTML Collection은 유사 배열 객체이면서 iterable이다.
모든 태그를 취득하는 방법으로는 document.getElementsByTagName("*")이 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<ul id="fruits">
<li>Apple</li>
<li>Banana</li>
<li>Grape</li>
</ul>
<ul>
<li>html</li>
</ul>
<script>
// 특정 요소 노드의 자손 노드를 탐색하여 반환할 수도 있다.
const $fruits = document.getElementById("fruits");
const $listFromFruits = $fruits.getElementsByTagName("li");
console.log($listFromFruits); // HTML Collection(3) [li, li, li]
</script>
</body>
</html>
getElementById
: HTML 문서 안에서 id 값은 고유한 값으로 아래의 키워드를 통하면 요소 그 차제를 취득할 수 있다. 다만 id가 중복으로 입력된 오류의 상황에서는 조건에 맞는 요소를 전부 검색하여 조건에 맞는 가장 첫번째 요소 노드를 반환한다. HTML 요소에 id를 부여하면 동일한 이름의 전역 변수가 암묵적으로 선언되고 거기에 해당 노드가 할당되는 효과
가 있다. <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div id="foo"></div>
<script>
console.log(foo == document.getElementById("foo")); // true
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div id="foo"></div>
<script>
let foo = 1;
// id와 동일한 이름의 전역 변수가 이미 선언되어 있으면 해당 변수에는 노드 객체가 재할당되지 않는다.
console.log(foo == document.getElementById("foo")); // false
</script>
</body>
</html>
querySelector
: CSS Selector는 스타일을 주고자하는 HTML 요소를 특정할 때 사용하는 문법인데 이 선택자를 사용하여 하나의 요소 노드를 반환할 수 있다. 단, 선택자를 만족시키는 요소 노드가 여러개일 경우, 첫 번째 요소 노드만 반환
한다.
querySelectorAll
: 인수로 전달한 CSS 선택자를 만족시키는 모든 요소를 NodeList 형태로 반환
한다.
출처: 모던 자바스크립트 Deep Dive-이웅모