DOM(Document Object Model, 문서 객체 모델) : HTML, XML 문서의 Programming-interface로, HTML과 Javascript가 상호작용할 수 있도록 하는 도구를 말한다.
DOM은 문서의 구조화된 표현(Structured representation)을 제공하고, Javascript와 같은 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공한다.
이를 돕는 것이 DOM API로, DOM 구조의 문서구조나, 스타일, 텍스트 내용 등을 변경할 수 있도록 돕는 역할을 한다.
DOM Tree는 HTML 문서의 태그(tag)를 노드의 계층 구조 트리로 표현한 것으로, 쉽게 말하면, HTML문서를 Node 구조의 tree 형태로 표시한 것을 말한다.
때문에 DOM구조는 Node Tree라고 부르기도 하며, console.dir
로 DOM에 있는 노드를 탐색할 수 있다.
💡 HTML → DOM Tree Parsing
![]()
![]()
Node(노드) : 노드는 추상 클래스로, 객체의 속성이다. 트리 주료구조에서는 트리를 구성하고 있는 객체 하나를 노드(Node)라고 한다.
: DOM Tree의 최상위 계층이면서 전체 문서를 가르키는 Document 객체이다.
document로 참조할 수 있으며, DOM Tree로 웹 페이지를 접근하는 시작점이다.
: HTML 태그에 해당 하는 노드로, 요소 노드는 속성 노드와 택스트 노트를 자식으로 가질 수 있다.
: 모든 HTML 요소의 속성은 속성 노드이며, 요소 노드에 관한 정보를 가지고 있다.
: HTML 문서의 모든 택스트는 택스트 노드로, 개행(줄바꿈), 공백과 같이 눈에 명시적으로 보이지 않는 요소가 바로 text node이다.
※ 각 요소 노드 사이에는 /n
과 같은 텍스트 노드가 존재한다.
: HTML 문서의 모든 주석 노드
Property(프로퍼티) : object(객체)의 속성을 의미하며, 프로퍼티는
key-value
의 한 쌍으로 표현된다.
노드 트리의 가장 상위에 위치하며, 루트 노드는 트리에서 단 하나만 존재한다.
루트 노드를 제외한 모든 노드는 단 하나의 부모 노드만을 가지며, 부모 노드는 여러개의 자식 요소를 가질 수 있다.
모든 요소 노드는 자식 노드를 가질 수 있으며, 자식 노드는 단 하나의 부모 노드를 가진다.
같은 부모 노드를 가지는 모든 노드는 형제 노드로, 같은 트리 레벨(tree level)에 존재하는 요소를 가리킨다.
부모 노드를 포함해 계층적으로 현재 노드보다 상위에 존재하는 노드를 기리킨다.
자식 노드를 포함해 계층적으로 현재 노드보다 하위에 존재하는 모든 노드를 가리킨다.
Node 객체의 프로퍼티를 이용해 조상, 부모, 자식, 형제 노드에 접근 할 수 있다.
기준 노드의 부모 노드를 참조하며, 만약 기준 노드가 Document 객체일 경우 부모 노드가 없으므로 parentNode는 null
이 된다.
기준 노드의 자식 노드의 참조가 저장된 유사 배열을 참조한다. 이때 유사 배열은 NodeList 형태이다.
기준 노드의 첫 번째 자식, 마지막 자식 노드를 참조하며, 자식 노드가 없는 경우 null
이 된다.
기준 노드와 같은 부모를 가진 다음 형제 노드 또는 이전 형레 노드를 참조한다.
노드 유형을 뜻하는 숫자를 참조한다.
(요소 노드 : 1 / 택스트 노드 : 3 / document : 9)
택스트 노드일 경우, 택스트 콘텐츠를, 요소 노드일 경우엔 null
을 반환한다.
Node 객체의 프로퍼티는 택스트 노드를 포함하고 있다. 때문에 DOM 트리 안의 택스느 노드는 무시하고, HTML 요소의 계층 구조만 가져오는 프로퍼티를 활용하는 방법도 있다.
기준 노드의 자식 요소 참조를 저장한 유사 배열 객체(NodeList)이다.
기준 노드의 부모 요소 객체를 참조(택스트 노드는 제외)
기준 노드의 첫 번째 자식 요소, 마지막 자식 요소 객체 참조(택스트 노드, 공백 노드 모두 제외)
기준 노드와 같은 부모를 가진 다음 형제 노드 객체 / 이전 형제 노드 객체 밴환
기준 노도의 자식 요소 개수를 반환 (= children.length)
Javascript의 거의 모든 객체는
Object
의 인스턴스로,Object.prototype
에서 속성과 메서드를 상속 또는 재정의할 수 있다.따라서 DOM에서 모든 객체들은 클래스(프로토타입)을 상속받는다.
👉
img
태그의 프로토타입을 살펴보자![]()
차례대로 Element Node(HTML Tag) → HTML
element
Element → HTMLElement → Element → Node → EventTarget → Object
drill
에서 알 수 있듯이, 기존 HTML 요소에 접근하여 요소의 속성이나 text 등 DOM 객체의 속성(firstElementChild 등)을 통해 DOM을 탐색하는 작업을 DOM Drilling이라고 한다.
script 파일은 비동기적으로 로드할 수 있도록 defer 속성을 추가한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Advanced javascript</title>
<script src="app.js" defer></script>
</head>
<body>
<h1>hi!</h1>
<p>
this is a
<a href="#">link</a> // ✔️
</p>
</body>
</html>
✔️ 체크 된 anchor 태그의 href 속성의 주소값을 변경한다.
document.body.children[1].children[0].href = 'https://google.com';
동적 UI에 최적화되어 있지 않다.
JavaScript에 DOM 요소를 조작하는 코드가 많다면, 브라우저 렌더링 시, DOM Tree와 CSSOM 트리를 다시 Parsing하여 Render Tree을 재생성하고, 이를 기반으로 리플로우와 리페인팅하는 과정이 무수히 많이 일어나게 된다.
이러한 DOM의 문제점을 해결하기 위해, React에서는 virtual DOM을 이용해 DOM 업데이트를 추상화하여 브라우저 렌더링을 최소화하여 최적화하는 작업을 수행한다.
Javascript에서 HTML 요소를 제어하기 위한 명령(API, Application Programming Interface)의 집합을 의미한다.
document.queryselector(CSS 선택자, id/class 선택자)
<!--HTML-->
<div class="this">1번 요소</div>
<div class="this">2번 요소</div>
<div class="this">3번 요소</div>
// JavaScript
document.querySelector('.this') // 1번 요소 하나만 선택된다.
document.queryselectorAll(CSS 선택자, id/class 선택자)
[index]
를 명시한다.<!--HTML-->
<div class="this">1번 요소</div>
<div class="this">2번 요소</div>
<div class="this">3번 요소</div>
// JavaScript
document.querySelectorAll('.this') // ["1번 요소", "2번 요소", "3번 요소"] < 배열로 표시
document.querySelectorAll('.this')[1] // 2번 요소를 선택
※ 이때 반환되는 배열은 배열과 모양은 유사하나, 엄밀히 말해 배열은 아니기 때문에 이를 유사배열(array-like)라고 한다.
<!--HTML-->
...
<p>this is p</p>
...
// JavaScript
const spanElement = document.queryselector('span');
.classList.add(클래스명)
// JavaScript
spanElement.classList.add('warning');
.classList.remove(클래스명)
// JavaScript
spanElement.classList.remove('warning');
.classList.contains(클래스명)
// JavaScript
spanElement.classList.contains('warning'); // true
spanElement.classList.contains('safe'); // false;
.addEventListner()
<!--HTML-->
<div id="target">여기에용</div>
<button id="changeBtn">">Change!</button>
// JavaScript
let changeBtn = document.getElementById('changeBtn');
let target = document.getElementById('target');
//지정할 셀렉터를 변수로 지정하여 아래의 코드 길이 줄이기
changeBtn.addEventListener('click', function() {
target.innerHTML = 'Text changed!';
})
그 밖에도 다양한 DOM API가 있다.
※ 참고자료