HTML 문서의 계층적 구조와 정보를 표현하며,
노드의 타입에 따라 프로퍼티와 메서드를 제공하는 트리형 자료구조.
브라우저의 렌더링 엔진은 HTML문서를 파싱하여 브라우저가 이해할 수 있는 자료구조 DOM을 생성한다.
HTML요소는 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소노드 객체로 변환됨.
HTML문서는 HTML요소들의 집합, 중첩관계를 가지며 이로 인해 계층적인 부자관계 형성.
-> *트리 자료구조로 구성
노드 객체 타입은 총 12개임.
1) 문서 노드 : DOM 트리 최상위에 존재하는 루트노드, document 객체(=브라우저가 렌더링한 HTML 문서 전체)를 가리킴, DOM 트리 노드들에 접근하기 위한 진입점 역할.
2) 요소 노드 : HTML 요소들을 가리키는 객체, 부자관계를 가지고 이를 통해 정보를 구조화 함.(부모 노드와 연결)
3) 어트리뷰트 노드 : HTML 요소의 어트리뷰트를 가리키는 객체, 요소노드에만 연결되어 있음.
4) 텍스트 노드 : 문서의 정보 표현, 요소 노드의 자식 노드이고 자식 가질 수 없는 리프노드(DOM 트리 최종단)
+ 코멘트 노드, 도큐먼트 노드 등등
DOM을 구성하는 노드 객체는 DOM API를 사용할 수 있음.
DOM API를 통해 탐색 가능하고, 조작도 가능함.
DOM을 구성하는 노드 객체는 표준 빌트인 객체가 아닌 호스트 객체.
(브라우저 환경에서 추가적으로 제공!)
하지만 노드 객체도 자바스크립트 객체이므로 프로토타입에 의한 상속구조를 가짐.
모든 노드객체는 공통적으로
Object(객체)
,EventTarget(이벤트 발생시키는 객체)
,
Node(트리 자료구조의 노드 객체로 트리 탐색, 정보 제공..)
인터페이스를 상속받음.
요소의 종류에 따라서도 고유한 기능들이 있음.
- 문서노드는
Document
,- 어트리뷰트 노드는
Attr
,- 텍스트 노드는
CharacterData
,- 요소노드는
Element 인터페이스
를 상속받음.
공통된 기능일수록 프로토타입 체인의 상위에 위치.
id
, class
, css
선택자등을 이용한 요소 노드 취득
querySelector
,getElementById
차이점
속도 면에서는 querySelector
< getElementById
이지만,
querySelector
메서드가 일관된 방식으로 요소 취득한다는 장점이 존재함.
getElementById
,공통점
DOM API가 여러개의 결과값을 반환하기 위한 DOM 컬렉션 객체,
둘 다 유사배열 객체이자 이터러블(for...of문으로 순회 가능)
노드 객체 상태 변화를 실시간으로 반영하는 살아있는 객체
차이점
HTMLCollection : 언제나 live 객체로 동작.
NodeList : 대부분은 실시간 반영하지 않고 과거의 정적 상태 유지하는 non-live 객체로 동작, 경우에 따라 live 객체 동작.
- 단점 및 해결방안
실시간으로 상태를 변경하기 때문에 문제가 발생할 가능성 존재.
-> HTMLCollection이나 NodeList 객체를 배열로 변환하여 사용.
새로운 노드를 생성하여 DOM에 추가하거나, 기존 노드를 삭제 또는 교체 하는 것을 이야기함.
DOM 조작에 의해 DOM에 새로운 노드가 추가되거나 삭제되면 리플로우/리페인트
가 일어남.
-> 성능에 영향을 미침.
innerHTML
장점 : DOM 조작 구현이 간단하고 직관적임.
단점 :
1) 크로스 사이트 스크립팅 공격에 취약
함.
2) HTML 마크업 문자열 할당하는 경우에 요소 노드 모든 자식 노드 제거하고 할당한 HTML 마크업 문자열 파싱하여 DOM 변경
3) 새로운 요소 삽입시 위치 지정이 불가함..
innerAdjactHTML
기존 요소에 영향 주지 않고, 새로 삽입될 요소만 파싱하여 자식 요소로 추가함.
innerHTML 보다 빠름!
BUT, 여전히 크로스 사이트 스크립팅 공격에 취약
DOM이 여러번 변경돠면 변경 횟수만큼 리플로우/리페인트
- 성능문제로 직결됨.
-> 해결법 : 컨테이너 요소 사용
(복수의 요소 노드들을 컨테이너 요소의 자식 노드로 추가하기)
- 장점 : DOM을 한 번만 변경
- 단점 : 불필요한 컨테이너 요소 추가
-> 해결 : DocumentFragment 노드 사용
부모노드가 없어 기존 DOM과는 별도로 존재 -> DocumentFragment 노드에 자식 추가하여도 기존 DOM에 변경 발생 X
DocumentFragment 노드를 DOM에 추가하면 자신은 제거되고, 자신의 자식 노드만 DOM에 추가됨.