DOM 이란?
텍스트 파일로 만들어져 있는 웹 문서를 브라우저에 렌더링 하려면 웹 문서를 브라우저가 이해할 수 있는 구조로 메모리에 올려야 한다. 브라우저의 렌더링 엔진은 웹 문서를 로드한 후, 파싱 하여 웹 문서를 브라우저가 이해할 수 있는 구조로 구성하여 메모리에 적재하는데 이를 DOM이라 한다.
- 즉 모든 요소와 요소의 어트리뷰트, 텍스트를 각각의 객체로 만들고 이들 객체를 부자 관계를 표현할 수 있는 트리구조로 구성한 것이 DOM이다.
- DOM은 자바스크립트를 통해 동적으로 변경할 수 있으며 변경된 DOM은 렌더링에 반영된다.
- 한 마디로 브라우저가 HTML 웹 페이지를 인식하는 방식을 계층화시켜 트리구조로 만든 객체(Object) 모델을 DOM이라 한다.
- DOM에는 node 와 element 개념이 나온다. node는 element의 상위 개념이라 한다. DOM이 각 노드별로 계층화된 트리구조이고, elemnet(태그)는 node의 종류 중 하나인 것이다. node의 종류는 텍스트 혹은 주석이 될 수 있다고 한다.
- 자바스크립트에서 DOM은 document 객체에 구현되어있다. 따라서 자바스크립트에서는 document.찾고자 하는 프로퍼티 이름으로 요소에 접근할 수 있다. 또한 DOM은 구조를 파악할 때 cosole.dir을 사용하면 편하다. mdn에서는 cosole.dir은 자바스크립트 객체의 모든 속성을 볼 수 있는 방법이라고 한다. 특정 객체의 하위 개체를 쉽게 파악할 수 있어서 DOM 요소를 조회할 때 사용하면 유용하다.
DOM은 HTML, ECMAScript에서 정의한 표준이 아닌 별개의 W3C의 공식 표준이며 플랫폼/프로그래밍 언어 중립적이다.
DOM은 다음 두 가지 기능을 담당한다.
HTML 문서에 대한 모델 구성
브라우저는 HTML 문서를 로드한 후 해당 문서에 대한 모델을 메모리에 생성한다.
이때 모델은 객체의 트리로 구성되는데 이것을 DOM tree라 한다.
HTML 문서 내의 각 요소에 접근 / 수정
DOM은 모델 내의 각 객체에 접근하고 수정할 수 있는 프로퍼티와 메소드를 제공한다.
DOM이 수정되면 브라우저를 통해 사용자가 보게 될 내용 또한 변경된다.
DOM 과 자바스크립트의 차이점
- DOM !== JavaScript : DOM 은 자바스크립트의 일부가 아니다.
- 웹 페이지는 일종의 문서인데, 이를 객체지향적으로 표현한 것이 바로 DOM 객체이다. 자바스크립트 같은 프로그래밍 언어로 DOM을 조작하고 수정할 수 있는 것은 맞지만, 엄밀히 말하면 둘은 독립적인 개념이다.
- MDN에 따른 정리는 다음과 같다. API(web) = DOM + JavaScript(스크립팅 언어)
- 프로그래밍 언어와 독립적으로 존재한다는 것은, 즉 자바스크립트가 아닌 다른 언어로도 DOM을 조작할 수 있다는 의미이다.
DOM tree 구조
DOM tree는 브라우저가 HTML 문서를 로드한 후 파싱하여 생성하는 모델을 의미한다. 객체의 트리로 구조화되어 있기 때문에 DOM tree라 부른다.
먼저 하나의 root(뿌리) node에서 시작된다.
- tree에서는 위쪽의 노드를 부모(parent)노드, 아래쪽 노드를 자식(child) 노드라고 한다.
- root node는 가장 위에서 시작되는 node이므로 parent(부모)가 없는 node가 되고, 이를 root(뿌리) node라고도 부른다.
- 반대로, children(자식)이 없는 node를 leaf(잎) node라고도 한다.
뿌리(root)에서 시작해 잎(leaf)에서 끝나는 것
DOM에서 모든 요소, 어트리뷰트, 텍스트는 하나의 객체이며 Document 객체의 자식이다. 요소의 중첩관계는 객체의 트리로 구조화하여 부자관계를 표현한다. DOM tree의 진입점(Entry point)은 document 객체이며 최종점은 요소의 텍스트를 나타내는 객체이다.
DOM tree 노드 구성
DOM tree는 네 종류의 노드로 구성된다.
문서 노드(Document Node)
트리의 최상위에 존재하며 각각 요소, 어트리뷰트, 텍스트 노드에 접근하려면 문서 노드를 통해야 한다.
즉, DOM tree에 접근하기 위한 시작점(entry point)이다.
요소 노드(Element Node)
요소 노드는 HTML 요소를 표현한다. HTML 요소는 중첩에 의해 부자 관계를 가지며 이 부자 관계를 통해 정보를 구조화한다.
따라서 요소 노드는 문서의 구조를 서술한다고 말 할 수 있다. 어트리뷰트, 텍스트 노드에 접근하려면 먼저 요소 노드를 찾아 접근해야 한다.
모든 요소 노드는 요소별 특성을 표현하기 위해 HTMLElement 객체를 상속한 객체로 구성된다.
어트리뷰트 노드(Attribute Node)
어트리뷰트 노드는 HTML 요소의 어트리뷰트를 표현한다.
어트리뷰트 노드는 해당 어트리뷰트가 지정된 요소의 자식이 아니라 해당 요소의 일부로 표현된다.
따라서 해당 요소 노드를 찾아 접근하면 어트리뷰트를 참조, 수정할 수 있다.
텍스트 노드(Text Node)
텍스트 노드는 HTML 요소의 텍스트를 표현한다.
텍스트 노드는 요소 노드의 자식이며 자신의 자식 노드를 가질 수 없다.
즉, 텍스트 노드는 DOM tree의 최종단이다.
DOM 사용해보기!
- DOM 으로 HTML Element 추가 후 기존 요소에 추가하기
// 새로운 div를 생성하여 tweetDiv 변수에 저장
const tweetDiv = document.createElement('div');
// container Id를 가진 요소를 조회하여 container 변수에 저장
const container = document.querySelector('#container');
// container에 tweetDiv 를 맨 마지막 자식 요소로 추가
container.append(tweetDiv);
- 생성한 HTML Element 변경하기
const oneDiv = document.createElement('div');
// 생성한 요소의 textContent 변경
oneDiv.textContent = 'dev'; // <div>dev<div>
// class 추가: 해당 클래스로 지정된 스타일이 있다면 동일하게 적용
oneDiv.classList.add('tweet');
// setAttribute로 요소의 어트리뷰트로 지정 가능
// 첫 번째 인자로 어트리뷰트 이름, 두 번째 인자로 어트리뷰트 값을 받는다.
oneDiv.setAttribute('id','yes');
- DOM으로 HTML Element 삭제하기
// 삭제할 요소 1개를 특정지을 수 있는 경우
tweetDiv.remove();
// 여러개의 요소를 삭제할 경우 : 반복문을 사용한다.
// 1. con.firstChild가 조회되는 동안 firstChild를 삭제.
// ... 이때 조건문을 수정하여 삭제되는 갯수 등을 제한할 수 있다.
while(con.firstChild){
con.removeChild(con.firstChild); }
// 2. 특정 클래스로 구성된 노드리스트를 순회하여 삭제
const twteets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
tweet.remove();
})
// or
for (let tweet of tweets){
tweet.remove()
}
- 모든 요소를 지우는 방법은 위 방법 이외에도 innerHtml 이라는 메서드가 존재한다. 다만 innerHtml 의 경우 외부인이 <scripts> 태그 내에 악성 코드를 심어 공격하는 XSS 에 취약하므로, 텍스크를 변경할 땐 textContent를, 요소 자체를 삽입할 때는 insertAdjacentHTML을 사용하는 것을 권장한다.
'코드스테이츠' 카테고리의 다른 글
Proxy 를 통해 CORS 에러 해결하기 (0) | 2023.06.07 |
---|---|
[Figma] - Figma 클론 (0) | 2023.04.17 |
[Figma] - Figma 개념 / Figma 컴포넌트 구현해보기! (0) | 2023.04.15 |
[JavaScript] - 프로토타입 체인 (0) | 2023.03.16 |
[JavaScript Koans] (0) | 2023.03.06 |