DOM은 Document Object Model (문서 객체 모델)의 약자로, HTML 요소를 Object 처럼 제어할 수 있는 Model이다. 쉽게 말해, Javascript를 사용할 수 있으면 DOM으로 HTML을 조작할 수 있다!
위의 글은 코드스테이츠 코스에서 DOM을 소개하며 나왔던 설명이다. 위의 설명이 잘 이해가 가지 않아 <모던 자바스크립트 Deep Dive> 책을 참고하여 브라우저 렌더링 과정부터 천천히 정리해본다.
본격적으로 들어가기에 앞서 모르는 용어 정리를 해보았다.
- 파싱(Parsing): 하나의 프로그램을 런타임 환경(ex)브라우저 내 자바스크립트 엔진)이 실제로 행할 수 있는 내부 포맷으로 분석하고 변환하는 것을 의미한다. 즉, 파싱은 문서의 내용을 토큰(문법적으로 더는 나눌 수 없는 코드의 기본 요소)으로 분석하고, 문법적 의미와 구조를 반영한 파스트리(어떤 문장을 트리구조로 나타내는 것)를 생성하는 과정이다.
- 렌더링(rendering): 렌더링이란 HTML, CSS, Javascript로 작성된 문서를 파싱하여 브라우저에 시각적으로 출력하는 것을 말한다.
브라우저의 핵심 기능은 필요한 리소스(HTML, CSS, JS 등)를 서버에 요청하고 서버로부터 응답을 받아 브라우저에 실시간으로 렌더링 하는 것이다.
이 때, 브라우저의 요청에 따라 서버로부터 응답 받은 HTML 문서는 문자열로 이루어진 순수한 텍스트이다. 순수한 텍스트인 HTML 문서를 브라우저에 시각적 픽셀로 보이도록 렌더링하려면 HTML 문서를 브라우저가 이해할 수 있는 자료구조인 객체로 변환하여 메모리에 저장해야 한다.
따라서, 브라우저의 렌더링 엔진은 응답받은 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 자료구조인 DOM을 생성한다.
즉, DOM은 HTML 문서를 파싱한 결과물이라고 할 수 있다.
DOM은 HTML 문서를 파싱한 결과물이기 때문에 HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 프로퍼티와 메서드를 제공하는 트리구조이다. 그러므로 JS를 이해하고 사용할 수 있으면 DOM으로 HTML을 조작할 수 있다!
그럼 이제 본격적으로 DOM에 대해서 차근차근 이해해보자.
<div id="hello">Hello</div>
//위의 html은 시작태그, 어트리뷰트 이름, 어트리뷰트 값, 콘텐츠, 종료태그로 이루어져 있다.
HTML 요소는 위의 주석과 같이 HTML 문서를 구성하는 개별적인 요소를 의미한다.
이 HTML요소는 렌더링 엔진에 의해 DOM이 생성될 때 DOM을 구성하는 요소 노드 객체로 변환된다.
즉, HTML 요소의 어트리뷰트는 DOM의 어트리뷰트 노드로, HTML 요소의 텍스트 콘텐츠는 DOM의 텍스트 노드로 변환된다.
<body>
<div class="calculator_button">
<div class="number">1</div>
<div class="number">2</div>
<div class="number">3</div>
<div class="operator">+</div>
</div>
</body>
위의 예시와 같이 HTML에서는 HTML 요소 간에 계층적인 부모-자식 관계가 형성된다.
이러한 HTML의 요소 간의 부모-자식 관계를 반영하여 DOM의 모든 노드 객체들은 트리 자료 구조로 구성된다.
트리 자료 구조
트리 자료 구조는 노드들의 계층 구조로 이루어진다.
즉, 트리 자료 구조는 부모 노드와 자식 노드로 구성되어 노드 간의 계층적 구조(부모, 형제 관계)를 표현하는 비선형 자료 구조를 말한다.
이러한 노드 객체들로 구성된 트리 자료 구조를 DOM이라고 부른다.
문서 노드 (document node)
DOM 트리의 최상위에 존재하는 루트 노드로서, document 객체를 가리킨다. 여기서 document 객체는 브라우저가 렌더링한 HTML 문서 전체를 가리키는 객체를 말한다.
HTML 문서당 document 객체는 유일하며, Dom 트리의 로트 노드로서 Dom 트리의 노드들에게 접근하기 위한 진입점 역할을 담당한다.
요소 노드 (element node)
HTML 요소를 가리키는 객체를 말한다. 위의 HTML 예시의 div, body 가 DOM 에서의 요소 노드이다. 요소 노드는 HTML과 같이 부모-자식 관계를 가지며 이 부모-자식 관계를 통해 정보를 구조화한다.
어트리뷰트 노드 (attribute node)
HTML 요소의 어트리뷰트를 가리키는 객체를 말한다. 어트리뷰트 노드는 해당 어트리뷰트가 지정된 HTML 요소의 요소 노드와 연결되어 있다. 단, 요소 노드가 부모 노드와 연결되어 있는 것과는 달리 어트리뷰트 노드는 오직 요소 노드에만 연결되어 있으므로 (부모 노드가 없으므로) 요소 노드의 형제 노드가 아니다. 그래서 어트리뷰트 노드에 접근하려면 먼저 요소 노드에 접근해야 한다.
텍스트 노드(text node)
HTML 요소의 텍스트를 가리키는 객체를 말한다. 이 텍스트 노드는 문서의 정보를 표현해준다. 텍스트 노드는 요소 노드의 자식 노드이며 또다른 자식 요소를 가질 수 없기 때문에 DOM 트리의 최종단에 위치해 있다. 그래서 텍스트 노드에 접근하려면 먼저 부모 노드인 요소 노드에 접근해야 한다.
위에서 언급했다시피, DOM은 HTML 문서를 파싱한 결과물이기 때문에 HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리구조이다. 즉, DOM의 노드 객체는 자신의 주소와 정보를 제어할 수 있는 DOM API를 사용할 수 있다.
DOM API를 통해 노드 객체는 자신의 부모, 형제, 자식 노드를 탐색할 수 있으며 자신의 어트리뷰트나 텍스트를 조작할 수도 있다.
이렇게 DOM API를 사용하기 위해 모든 노드 객체는 Object, EventTarget, Node 인터페이스 등을 상속받는다. 노드 객체의 상속은 chrome 개발자 도구의 Element 패널 우측의 Properties 패널을 통해 확인할 수 있다.
DOM의 기초에 대해서 천천히 이해해 보는 시간을 가져보았다. 위의 내용을 정리해보면 다음과 같다.
DOM은 브라우저의 렌더링 엔진에 의해 HTML 문서를 파싱한 결과물이다.
그렇기 때문에 DOM은 HTML 문서의 계층적 구조와 정보를 표현하며 DOM의 노드 객체는 자신의 주소와 정보를 제어할 수 있는 DOM API를 사용할 수 있다.
이 DOM API를 통해 우리는 HTML의 구조나 내용 또는 스타일 등을 동적으로 조작할 수 있다!
이렇게 천천히 정리해보니 DOM에 대해 이해하기가 한결 편해진 것 같다. 이제 다음 TIL을 통해 본격적으로 DOM을 사용하는 방법을 알아본다.