1. DOM 이라는 단어가 가진 모호성
-
DOM 은 바라보는 관점에 따라 여러가지로 표현될 수 있다.
- 문서의 성격에 따라 DOM 을 다르게 표현하는 가장 큰 이유 중 하나이다.
2. 용어 정리
- 브라우저의 주요 구성 요소
-
인터페이스 관점에서 바라본 DOM: DOM Interfaces(Attr, Document Interface 등), HTML Interfaces(HTMLHtmlElement Interface 등), SVG Interfaces(SVGAElement Interface 등) 등을 포함한 Programing Interface 를 의미한다.<p />
-
API 관점에서 바라본 DOM: 특정 플랫폼 상에서 특정 언어(C++, JAVA, JS 등)를 통해 Programing Interface 를 구현한 API 를 의미한다.<p />
-
구현된 API 는 두 가지 형태로 나눌 수 있다.
-
엔진 내부에 구현된 API<p>
-
webkit 엔진은 C++ 언어를 통해 Programing Interface 를 구현한 API 를 사용한다.<p>
-
해당 인터페이스를 작성하기 위해 인터페이스 정의 언어(*.idl) 를 사용한다.<p>
-
HTMLHtmlElement.idl, HTMLHtmlElement.h, HTMLHtmlElement.cpp<p>
-
-
DOM 트리(or Parse 트리)를 JS 로 제어하기위해 구현된 API(즉 문서(HTML 등)의 Element 를 제어하기 위한 API 이다)<p>
-
HTMLHtmlElement 인터페이스 명세에는, 문서의 DTD version 정보를 반환받기 위한 속성이 명세되어있으며, 이 속성은 아래와 같이 구현되어있다.
-
HTMLHtmlElement 는 root element(html)를 위한 인터페이스이다.<p>
// HTMLHtmlElement 생성자 함수 객체 console.log(HTMLHtmlElement); // HTMLHtmlElement 생성자 함수 객체의 원형 console.log(HTMLHtmlElement.prototype);
원형(prototype) 객체 내부에는 version 속성이 구현되어있다.
또한 html element 를 가리키는 Document.documentElement 객체를 통해, version 정보를 가져올 수 있다.
console.log(document.documentElement); // html element object console.log(document.documentElement.version); // dtd version
-
Document.documentElement 객체의 __proto__ 속성은 HTMLHtmlElement 함수 객체의 원형(prototype) 을 가리키고 있다.
-
즉 document.documentElement 객체는 HTMLHtmlElement 생성자 함수 객체로 생성된 객체라는것을 알 수 있다.<p>
// 위임 과정을 통해 HTMLHtmlElement.prototype 객체가 생성된 document.documentElement 객체의 __proto__ 속성으로 위임된다. console.dir(document.documentElement.__proto__ === HTMLHtmlElement.prototype); // true
-
-
Element 를 생성하기 위한 모든 생성자 함수(HTMLHtmlElement, HTMLHeadElement 등) 객체는 명시적으로 호출 할 수 없으며, 원형 객체의 속성에도 접근할 수 없다.
-
Element 생성자 함수 객체에 대한, 접근 권한을 두고 있는듯 하다.<p>
try { // HTMLHtmlElement 생성자 함수 객체를 호출한다. console.dir(HTMLHtmlElement()); } catch(e){ console.log(e.message); // Illegal constructor } try { // 원형(prototype) 객체에 구현된 version 속성에 접근한다. console.dir(HTMLHtmlElement.prototype.version); } catch(e){ console.log(e.message); // llegal invocation } try { // HTMLHeadElement 생성자 함수 객체를 호출한다. console.dir(new HTMLHeadElement()); } catch(e){ console.log(e.message); // Illegal constructor }
-
-
document.createElement 함수는 암묵적으로 Element 를 생성하기위한 방법 중 하나이다.
// 암묵적으로 html element 를 생성할 수 있다. var html = document.createElement('html'); console.log(html.version); // dtd version
-
-
-
-
-
3. 어휘 분석과 구문 분석 과정
- 문서 분석 과정
-
DOM 트리(or Parse 트리) 생성 과정을 이해하기위해서는, 먼저 문서를 분석하는 과정인 어휘 분석과 구문 분석 과정을 이해해야한다.
-
어휘분석(lexical analysis): 문서의 내용을 의미 있는 문자(태그)로 분리하여 토큰화 시키는 과정을 말한다.<p>
-
생성된 토큰은 태그 이름, 속성 이름, 속성 값이 포함된 객체로 나타낼 수 있다.
var token = {tagName: 'a', attrs: [{name: 'href', value: 'http://google.com'}, {name: 'target', value: '_blank'}]};
-
-
구문분석(syntax analysis): 생성된 토큰을 Parser(구문 분석기)를 통해, 노드화(노드 객체) 시킨 후 DOM 트리에 추가시키는 과정을 말한다.
4. DOM 트리 생성 과정
-
HTML 파싱 시퀀스 다이어그램
-
브라우저는 디스크나 네트워크를 통해 해당 문서를 바이트 코드로 읽어드린 후, 지정된 인코딩 값(or 방식)에 따라 원시 데이터인 문자열로 변환한다.
- 바이트 코드: 프로그램이 컴파일된 형태
-
변환된 문자열을 의미 있는 문자(태그)로 분리하여 토큰화 시킨다.
-
토큰이 가진 tagName 과 일치하는 HTMLElement 를 생성 후 해당 속성을 추가시킨다.
-
부모 노드의 자식 노드로 생성된 HTMLElement 를 추가 시킨다(즉 DOM 트리에 반영시킨다)<p>
// tagName 을 통해 Element 를 생성한다. var elem = createHTMLElement(token.tagName); // 속성을 추가 시킨다. elem.setAttrs(token.attrs); // 부모 노드의 자식 노드로 해당 Element 를 추가 시킨다. parentNode.appendChild(elem);