DOM(Document Object Model)

10 Dec 2015

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>

        • 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);
    

관련 URL

comments powered by Disqus