문서 객체 모델 DOM은 무엇인가? - DOM의 개념, 종류, 구조 등
문서 객체 모델 (DOM)이란?
문서 객체 모델(DOM, Document Object Model)은 웹 페이지에 대한 인터페이스 입니다. DOM은 문서 내의 모든 요소를 정의하고, 페이지의 콘텐츠 및 구조, 스타일 등 각각의 요소에 접근하여 읽고 조작할 수 있는 API를 제공합니다.
즉, 모든 요소와 요소의 어트리뷰트, 텍스트를 각각의 객체로 만들고 이들 객체를 부자관계를 표현할 수 있는 트리 구조로 구성한 것이 DOM이다. 이 DOM은 자바스크립트를 통해 동적으로 변경할 수 있으며 변경된 DOM은 렌더링에 반영된다.
이러한 DOM은 HTML, ECMAScript에서 정의한 표준이 아닌 W3C의 표준 객체 모델이며, 아래와 같이 계층 구조를 가지고 있습니다.
DOM이 담당하는 기능
1. HTML 문서에 대한 모델 구성
브라우저는 HTML 문서를 로드한 후 해당 문서에 대한 모델을 메모리에 생성합니다.
이때, 모델은 객체의 트리로 구성됩니다. - DOM tree
2. HTML 문서 내의 각 요소에 접근 및 수정
DOM은 모델 내의 각 객체에 접근하고 수정할 수 있는 프로퍼티와 메서드를 제공합니다.
DOM이 수정되면 브라우저를 통해 사용자가 보게 될 내용이 변경됩니다.
DOM의 요소 접근
1. 하나의 요소 노드 선택 (DOM Query)
document.getElementById(id)
- id 값으로 요소 노드를 한 개 선택한다. (복수개가 선택된 경우, 첫번째 요소만 선택)
- Return : HTML Element를 상속받은 객체
<html>
<head>
<style>
.red { color: #ff0000; }
.blue { color: #0000ff; }
</style>
</head>
<body>
<div>
<h1>Color</h1>
<ul>
<il id="one" class="red">RED</il>
<il id="two" class="blue">BLUE 1</il>
<il id="thr" class="blue">BLUE 2</il>
<il id="four" class="blue">BLUE 3</il>
</ul>
</div>
</body>
</html>
// id로 하나의 요소 select
var element = document.getElementById('one');
// 클래스 어트리뷰트 값 변경
element.className = 'blue';
// 그림 DOM tree 참고
console.log(element); // <li id="one" class="blue">BLUE</li>
console.log(element.__proto__); // HTMLLiElement
console.log(element.__proto__.__proto__); // HTMLElement
console.log(element.__proto__.__proto__.__proto__); // Element
console.log(element.__proto__.__proto__.__proto__.__proto__); // Node
document.querySelector(cssSelector)
- CSS 셀렉터를 사용하여 요소 노드를 한개 선택한다. (복수개가 선택된 경우, 첫번째 요소만 선택)
- Return : HTML Element를 상속받은 객체
// css 셀렉터를 활용한 요소 선택
var element = document.querySelector('li.red');
// 클래스 어트리뷰트 값 변경
element.className = 'blue';
2. 여러 개의 요소 노드 선택 (DOM Query)
Class 이름 값으로 요소 선택
document.getElementByClassName(class)
- class 이름 값으로 요소 노드를 모두 선택한다. (구분을 공백으로 하여 여러개의 class 지정도 가능)
- Return : HTML Collection(live)
var elements = document.getElementByClassName('blue');
for(var i=0; i<elements.length; i++) {
console.log(elements[i]);
// elements[i].className = 'red'; 아래 예시 참고
}
만약 여기서 반복문을 통해 클래스 어트리뷰트의 값을 변경할 경우 예상대로 동작하지 않을 것이다.
getElementByClassName 메서드의 반환 값은 HTMLCollection이다. 이것은 배열과 비슷하지만 배열은 아닌 유사배열(array-like object)
이다.
이 HTMLCollection은 실시간으로 Node의 상태를 변경하기 때문에 위처럼 반복문을 통해 만약 elements[i].className = 'red';
(위 예제 주석참고)와 같이 변경하려 한다면 예상대로 동작하지 않는다.
- i가 0일 때 elements의 첫 요소 (li #two .blue)의 class 어트리뷰트의 값이 calssName 프로퍼티에 의해 blue에서 red로 변경된다.
- 이때, elements는 실시간으로 Node의 상태를 변경하기 때문에 변경된 첫번째 요소는 메서드의 인자로 지정한 선택 조건 ('blue')와 더이상 부합하지 않게 되어 반환 값에서 실시간으로 제거된다.
이처럼 HTMLCollection은 실시간으로 Node의 상태 변경을 반영하기 때문에 loop가 필요한 경우 반복문을 역방향으로 돌리거나 while 반복문을 사용하면 된다.
이 외에 아래와 같은 방법도 있다.
- 태그명으로 요소를 모두 선택하는
document.getElementByTagName(tagName)
- 지정된 CSS 선택자를 사용하여 요소를 모두 선택하는
document.querySelectorAll(selector)
'Web' 카테고리의 다른 글
[Web] 웹 서버(Web Server)와 WAS(Web Application Server)의 차이에 대하여 (0) | 2021.07.13 |
---|---|
DataTables 사용법 및 예제 JSON, jQuery - Grid 라이브러리 (0) | 2021.05.06 |
[React 리액트] 크롬에 React 디버깅 툴 설치 방법 (React Developer Tools) (0) | 2021.03.29 |
[Web/Ajax] Ajax란 무엇인가? 개념 및 동작 원리 (0) | 2020.12.24 |