본문으로 바로가기

HTMLElement 객체와 DOM Tree

이 포스팅에서는 HTMLElement 객체와 DOM(Document Object Model)에 대해 알아봅니다.


문서 개체 모델(Document Object Model, DOM) 은 자바스크립트 Node 개체의 계층화된 트리입니다.

HTML 문서를 작성할 때에는 HTML 콘텐츠를 다른 HTML 콘텐츠 내에 캡슐화하게 되는데, 이를 통해 트리(tree)로 표현 가능한 계층 구조가 만들어집니다.

대개 이러한 계층 구조나 캡슐화 시스템은 HTML 문서 내에서 들여쓰기 표시를 통해 시각적으로 표시됩니다.

브라우저는 HTML 문서를 로딩 시 이 계층 구조를 해석해서 마크업이 어떻게 캡슐화되었는지를 보여주는 노드 개체 트리를 생성합니다.

브라우저는 HTML 코드를 해석해서 트리 형태로 구조화된 노드들을 가지고 있는 문서(DOM)를 생성합니다.

다시 말해, HTML 문서가 실제 문서를 나타내는 노드 개체들의 트리 구조로 변환(브라우저의 해석에 의해)된다는 것입니다.



DOM Tree

모든 엘리먼트는 HTMLElement의 자식입니다. 따라서 HTMLElement의 프로퍼티를 똑같이 가지고 있습니다. 

동시에 엘리먼트의 성격에 따라서 자신만의 프로퍼티를 가지고 있는데 이것은 엘리먼트의 성격에 따라서 달라집니다. 

HTMLElement는 Element의 자식이고 Element는 Node의 자식입니다. Node는 Object의 자식입니다. 

이러한 관계를 DOM Tree라고 합니다.

이 관계를 그림으로 나타내면 아래와 같습니다.



HTMLElement 객체

getElement* 메소드를 통해서 원하는 객체를 조회했다면 이 객체들을 대상으로 구체적인 작업을 처리해야 합니다. 

이를 위해서는 획득한 객체가 무엇인지 알아야 하고 그래야 적절한 메소드나 프로퍼티를 사용할 수 있습니다.


다음의 코드는 getElement*의 리턴 값을 보여주고 있습니다.

html
<ul>
    <li>HTML</li>
    <li>CSS</li>
    <li id="active">JavaScript</li>
</ul>
<script>
    var li = document.getElementById('active');
    console.log(li.constructor.name);      // HTMLLIElement 
    var lis = document.getElementsByTagName('li');
    console.log(lis.constructor.name);    // HTMLCollection
</script>


이것을 통해서 알 수 있는 것은 아래와 같습니다.

  • document.getElementById - 리턴 데이터 타입은 HTMLLIELement 
  • document.getElementsByTagName - 리턴 데이터 타입은 HTMLCollection


즉 실행결과가 하나인 경우 HTMLLIELement, 복수인 경우 HTMLCollection을 리턴하고 있는 것입니다.


실행결과가 하나인 엘리먼트들을 좀 더 살펴봅니다.

html
<a id="anchor" href="http://naver.com">네이버</a>
<ul>
    <li>HTML</li>
    <li>CSS</li>
    <li id="list">JavaScript</li>
</ul>
<input type="button" id="button" value="button" />
<script>
    var target = document.getElementById('list');
    console.log(target.constructor.name);
 
    var target = document.getElementById('anchor');
    console.log(target.constructor.name);
 
    var target = document.getElementById('button');
    console.log(target.constructor.name);

   // 실행결과
   // HTMLLIElement
   // HTMLAnchorElement
   // HTMLInputElement
</script>


이를 통해서 알 수 있는 것은 엘리먼트의 종류에 따라서 리턴되는 객체가 조금씩 다르다는 것입니다. 

각각의 객체의 차이점을 알아봅니다. 

다음의 링크는 DOM의 스팩을 볼 수 있습니다.



HTMLLIElement 스펙

인터스페이스 스펙
interface HTMLLIElement : HTMLElement {
           attribute DOMString       type;
           attribute long            value;
};


HTMLAnchroElement 스펙

인터스페이스 스펙
interface HTMLAnchorElement : HTMLElement {
           attribute DOMString       accessKey;
           attribute DOMString       charset;
           attribute DOMString       coords;
           attribute DOMString       href;
           attribute DOMString       hreflang;
           attribute DOMString       name;
           attribute DOMString       rel;
           attribute DOMString       rev;
           attribute DOMString       shape;
           attribute long            tabIndex;
           attribute DOMString       target;
           attribute DOMString       type;
  void               blur();
  void               focus();
};


즉 엘리먼트 객체에 따라서 프로퍼티가 다르다는 것을 알 수 있습니다. 

하지만 모든 엘리먼트들은 HTMLElement를 상속 받고 있습니다.

  • interface HTMLLIElement : HTMLElement { 
  • interface HTMLAnchorElement : HTMLElement {


HTMLElement 인터페이스는 아래와 같습니다다.

인터페이스 스펙
interface HTMLElement : Element {
           attribute DOMString       id;
           attribute DOMString       title;
           attribute DOMString       lang;
           attribute DOMString       dir;
           attribute DOMString       className;
};



HTMLCollection

HTMLCollection은 리턴 결과가 복수인 경우에 사용하게 되는 객체입니다. 

유사배열로 배열과 비슷한 사용방법을 가지고 있지만 배열은 아니라는 점을 기억해야 합니다.


HTMLCollection의 목록은 실시간으로 변경됩니다. 

아래 코드를 살펴봅니다

html
<!DOCTYPE html>
<html>
<body>
<ul>
    <li>HTML</li>
    <li>CSS</li>
    <li id="active">JavaScript</li>
</ul>
<script>
    console.group('before');
    var lis = document.getElementsByTagName('li');
    for(var i = 0; i < lis.length; i++){
        console.log(lis[i]);
    }
    console.groupEnd();
    console.group('after');
    lis[1].parentNode.removeChild(lis[1]);
    for(var i = 0; i < lis.length; i++){
        console.log(lis[i]);
   }
   console.groupEnd();
</script>
</body>
</html>


결과



Jaehee's WebClub


[출처] 생활코딩


'JavaScript > DOM(Document Object Model)' 카테고리의 다른 글

event 란 무엇인가?  (0) 2016.03.04
Document 객체 & Text 객체  (0) 2016.03.03
Node Object(노드 객체)  (0) 2016.03.02