DOM과 DOM 트리(DOM tree)

hsmurf·2024년 1월 21일

javascript

목록 보기
1/3
post-thumbnail

DOM이란?

Document Object Model의 약자로, 한국어로는 문서 객체 모델.
HTML, XML 문서의 프로그래밍 인터페이스이다. 웹 페이지를 스크립트나 프로그래밍 언어를 통해 동적으로 조작할 수 있도록 해준다.간단하게 표현하면 웹 페이지에 나타나는 HTML 문서 전체를 객체로 표현한 것이며, 이때 각 객체를 노드(Node)라는 용어로 표현하고, 태그는 요소 노드, 문자는 텍스트 노드로 구분한다.

DOM의 역할

  1. 구조화된 문서 표현: HTML이나 XML 문서를 트리 구조로 변환하여 각 요소를 객체로 표현

  2. 동적 조작: JavaScript를 사용하여 DOM을 조작하여 웹 페이지의 내용, 구조, 스타일을 변경할 수 있음.

  3. 이벤트 처리: 사용자의 상호 작용에 따라 이벤트를 처리하고 반응할 수 있도록 함.


DOM트리(DOM tree)

DOM tree는 브라우저가 HTML 문서를 로드한 후 파싱하여 생성하는 모델을 의미한다. 객체의 트리로 구조화되어 있기 때문에 DOM tree라 부른다.

DOM에서 모든 요소, 어트리뷰트, 텍스트는 하나의 객체이며 Document 객체의 자식이다.
요소의 중첩관계는 객체의 트리로 구조화하여 부모-자식 관계를 표현한다.
DOM tree의 진입점(Entry point)는 document 객체이며 최종점은 요소의 텍스트를 나타내는 객체이다.

DOM tree는 네 종류의 노드로 구성된다.

문서 노드(Document Node)
트리의 최상위에 존재하며 각각 요소, 어트리뷰트, 텍스트 노드에 접근하려면 문서 노드를 통해야 한다. 즉, DOM tree에 접근하기 위한 시작점(entry point)이다.

요소 노드(Element Node)
요소 노드는 HTML 요소를 표현한다. HTML 요소는 중첩에 의해 부자 관계를 가지며 이 부자 관계를 통해 정보를 구조화한다. 따라서 요소 노드는 문서의 구조를 서술한다고 말 할 수 있다. 어트리뷰트, 텍스트 노드에 접근하려면 먼저 요소 노드를 찾아 접근해야 한다. 모든 요소 노드는 요소별 특성을 표현하기 위해 HTMLElement 객체를 상속한 객체로 구성된다.

어트리뷰트 노드(Attribute Node)
어트리뷰트 노드는 HTML 요소의 어트리뷰트를 표현한다. 어트리뷰트 노드는 해당 어트리뷰트가 지정된 요소의 자식이 아니라 해당 요소의 일부로 표현된다. 따라서 해당 요소 노드를 찾아 접근하면 어트리뷰트를 참조, 수정할 수 있다.

텍스트 노드(Text Node)
텍스트 노드는 HTML 요소의 텍스트를 표현한다. 텍스트 노드는 요소 노드의 자식이며 자신의 자식 노드를 가질 수 없다. 즉, 텍스트 노드는 DOM tree의 최종단이다.


HTML 콘텐츠 조작(Manipulation)

1. HTML 콘텐츠 조작

TML 콘텐츠를 조작(Manipulation)하기 위해 아래의 프로퍼티 또는 메소드를 사용할 수 있다. 마크업이 포함된 콘텐츠를 추가하는 행위는 크로스 스크립팅 공격(XSS: Cross-Site Scripting Attacks)에 취약하므로 주의가 필요하다.

textContent

요소의 텍스트 콘텐츠를 취득 또는 변경한다. 이때 마크업은 무시된다. 
textContent를 통해 요소에 새로운 텍스트를 할당하면 텍스트를 변경할 수 있다. 
이때 순수한 텍스트만 지정해야 하며 마크업을 포함시키면 문자열로 인식되어 그대로 출력된다.
innerText

innerText 프로퍼티를 사용하여도 요소의 텍스트 콘텐츠에만 접근할 수 있다. 
하지만 아래의 이유로 사용하지 않는 것이 좋다.

1. 비표준이다.
2. CSS에 순종적이다. 
   예를 들어 CSS에 의해 비표시(visibility: hidden;)로 지정되어 있다면 텍스트가 반환되지 않는다.
3. CSS를 고려해야 하므로 textContent 프로퍼티보다 느리다
innerHTML

해당 요소의 모든 자식 요소를 포함하는 모든 콘텐츠를 하나의 문자열로 취득할 수 있다. 
이 문자열은 마크업을 포함한다.

2. DOM 조작 방식

innerHTML 프로퍼티를 사용하지 않고 새로운 콘텐츠를 추가할 수 있는 방법은 DOM을 직접 조작하는 것이다. 한 개의 요소를 추가하는 경우 사용한다. 이 방법은 다음의 순서에 따라 진행한다.

  1. 요소 노드 생성 createElement() 메소드를 사용하여 새로운 요소 노드를 생성한다. createElement() 메소드의 인자로 태그 이름을 전달한다.

  2. 텍스트 노드 생성 createTextNode() 메소드를 사용하여 새로운 텍스트 노드를 생성한다. 경우에 따라 생략될 수 있지만 생략하는 경우, 콘텐츠가 비어 있는 요소가 된다.

  3. 생성된 요소를 DOM에 추가 appendChild() 메소드를 사용하여 생성된 노드를 DOM tree에 추가한다. 또는 removeChild() 메소드를 사용하여 DOM tree에서 노드를 삭제할 수도 있다

3. insertAdjacentHTML()

insertAdjacentHTML(position, string)

인자로 전달한 텍스트를 HTML로 파싱하고 그 결과로 생성된 노드를 DOM 트리의 지정된 위치에 삽입한다. 첫번째 인자는 삽입 위치, 두번째 인자는 삽입할 요소를 표현한 문자열이다. 첫번째 인자로 올 수 있는 값은 아래와 같다.


innerHTML vs DOM 조작 방식 vs insertAdjacentHTML()

  • innerHTML

    장점단점
    DOM 조작 방식에 비해 빠르고 간편하다.XSS공격에 취약점이 있기 때문에 사용자로 부터 입력받은 콘텐츠(untrusted data: 댓글, 사용자 이름 등)를 추가할 때 주의하여야 한다.
    간편하게 문자열로 정의한 여러 요소를 DOM에 추가할 수 있다해당 요소의 내용을 덮어 쓴다. 즉, 비효율적으로 HTML을 다시 파싱한다.
    콘텐츠를 취득할 수 있다.
  • DOM 조작 방식

    장점단점
    특정 노드 한 개(노드, 텍스트, 데이터 등)를 DOM에 추가할 때 적합하다.innerHTML보다 느리고 더 많은 코드가 필요하다.
  • insertAdjacentHTML()

    장점단점
    간편하게 문자열로 정의된 여러 요소를 DOM에 추가할 수 있다.XSS공격에 취약점이 있기 때문에 사용자로 부터 입력받은 콘텐츠(untrusted data: 댓글, 사용자 이름 등)를 추가할 때 주의하여야 한다.
    삽입되는 위치를 선정할 수 있다.

결론
innerHTML과 insertAdjacentHTML()은 크로스 스크립팅 공격(XSS: Cross-Site Scripting Attacks)에 취약하다. 따라서 untrusted data의 경우, 주의하여야 한다. 텍스트를 추가 또는 변경시에는 textContent, 새로운 요소의 추가 또는 삭제시에는 DOM 조작 방식을 사용하도록 한다.

profile
꿈을 코드로 구현 중

0개의 댓글