DOM은 무엇인가? DOM Node와 Element의 차이

ㅇ.ㅇ·2022년 7월 9일

여행자보험의 보장명과 보장가격을 가져오기 위해
웹크롤링을 해보았다. 사실 이 과정은 그냥
html parsing 해주는 라이브러리를 사용해서 html에서 내가 원하는 정보를 가져오는 것이 전부였다.
원하는 결과가 무엇인지 내가 무엇을 해야하는지 명확했지만 그 결과를 얻기 위한 과정에서 어려움이 있었다.
element, node에 대한 차이를 이해하지 못했기 때문이다.

브라우저의 dom에 대해 다시 학습하고, element와 node의 차이가 무엇인지 정리해보고자 한다

dom

dom은 document object model의 줄임말이며,
웹페이지에 대한 인터페이스라고 한다
dom이 인터페이스 이므로, 우리는 dom을 통해 웹페이지의 컨텐츠, 구조, 스타일을 읽고 조작할 수 있다.

웹페이지는 어떻게 빌드되는가

브라우저가 html파일을 읽어와서 화면에 띄어주는 과정은 'critical rendering path'라고 불린다. 이 과정을 크게 두 가지로 나누자면 (1) 브라우저가 html과 css를 파싱하여 결국 화면에 어떤것이 보여지게 되는지 결정하는 과정과 (2) 브라우저가 렌더링을 하는 과정이다.

(1)번 과정을 거치면, 렌더트리가 만들어진다. 렌더트리는 화면에 보여지게 되는 html element와 그에 대응하는 스타일을 표현한 것이다. 렌더트리가 만들어지기 위해서는 cssom과 dom이 필요하다

Dom은 어떻게 만들어지는가

Dom은 Html 문서를 객체 기반으로 표현한 것이다.
왜 객체로 표현했을까? 이는 HTML의 구조와 내용을 객체 모델로 바꿔서 다양한 프로그램에서 쉽게 사용할 수 있게 하기 위함이다.

DOM의 객체 구조는 '노드 트리'라고도 불린다. 왜냐하면 DOM을 루트에서부터 여러 노드들이 가지치며 나오는 트리로 생각할 수 있기 때문이다. 루트의 element로 부터 중첩된 여러 element가 뻗어나오게 되며 말단 노드에는 각 element의 content가 있는 형태이다.

다음의 html 문서는 아래와 같은 노드 트리로 표현된다. html 태그로부터, head, body node가 나오게 되며, 트리의 leaf에는 컨텐츠들이 있는 것을 확인할 수 있다.

  <html>
    <head>
      <title> My title </title>
    </head>
    <body>
      <h1>My header</h1>
      <a hef='#'>My Link</a>
    </body>
  </html>

Dom이 아닌 것은 무엇인가

dom이 html문서와 1대1로 매핑되는 것처럼 보이지만 좀더 자세히 알아보며 그 차이를 이해해야한다.

dom은 원본 html이 아니다

dom이 html 문서로부터 만들어지긴했지만, 항상 정확하게 같지는 않다.

  • 차이점 1 : html이 유효하지 않을 경우
    dom은 오로지 유효한 html문서에 대한 인터페이스이다. html을 파싱하며 dom을 생성하는 과정에서 브라우저는 html에서 문제가 있는 것들을 고칠 수도 있다.
    예를들어, 아래의 html과 같이 와 가 빠진 유효하지 않은 html의 경우 dom은 head와 body를 추가하여 유효한 html로 고치게 된다.

    <!doctype html>
    <html>
      Hello, world!
    </html>

    - 차이점 2 : dom이 자바스크립트에 의해 수정되었을 경우

    dom은 정적인 것이 아니고, 동적으로 변경될 수 있다. js가 dom에 수정을 가할 수 있는데, dom에 노드를 추가하거나 수정하는 등의 작업을 할 수 있다. 그러나 js가 dom에 수정을 가할 수 있는데, dom에 노드를 추가하거나 수정하는 등의 작업을 할 수 있다. 그러나 js가 dom을 변경하다고 하여서 html이 변경되는 것이 아니다.
    dom이 브라우저에서 보여지는 것은 아니다.
    브라우저 화면에서 보여지는 것은 렌더 트리이며, 렌더트리는 dom과 cssom을 합쳐서 구성하게 된다. dom과 렌더트리의 차이는 렌더트리는 화면에 페인트될 것으로 구성되어있다는 것이다.

    렌더트리는 오로지 무엇이 렌더링될지에 대해 관심을 갖기 때문에 보여지지 않는 부분은 렌더트리에서 제외가 된다.
    display:none 속성이 있는 element는 dom에는 있지만 보여지지 않기 때문에 렌더트리에는 빠진다.

    단, visibility: hidden은 마찬가지로 화면에 보이지는 않지만 렌더트리에는 포함된다.
    따라서 visibility: hidden으로 숨겨진 element는 보이지는 않지만, 실제 화면에서 그 공간을 차지하고는 있다.

    dom이 devtool에 있는 것과 같은 것이 아니다.
    devtool은 dom에 가가운 것을 제공한다. 그러나
    데브툴은 dom에 없더라도 우리에게 정보를 주기 위해 추가로 넣는 것들이 있다.

    그 예로는 css의 pseudo element가 있다.
    pseudo-element는 cssom과 렌더트리로부터 ::before와 ::after 셀렉터로 만들어지게 된다. 그러나, dom에는 속하지 않는다. dom은 html로부터 만들어지기때문에 그 element와 스타일은 포함하지 않기 때문이다.

    pseudo-element가 dom의 구성은 아니지만, devtool은 그것을 보여진다 하더라도, js로 그 엘리먼트를 target할 수는 없는 것이다.


    Dom node와 element의 차이점

    🍕 DOM Node

    DOM은 Node의 계층 구조로 이루어져 있다. 각 노드는 부모와 children을 가질 수 있다.

    <!DOCTYPE html>
    <html>
      <head>
        <title>My Page</title>
      </head>
      <body>
        <!-- Page Body -->
        <h2>My Page</h2>
        <p id="content">Thank you for visiting my web page!</p>
      </body>
    </html>
        

    위의 html은 아래에 있는 노드들의 계층으로 구성되어있다.

html에 있는 tag(<html>,<p>와 같은...)들은 node를 표현하게 된다. 여기서 그저 text이더라도 node가 된다는 점이다. 노드트리를 보면, <p>자식노드로 text node가 있는 것을 확인할 수 있다.

  • Node Type

Node.Element_node 외에도, 주석의 타입인 comment_node와 전체 document tree를 표현하는 Node.Document_node도 있다.

DOM Element

Element는 node의 특정 타입 즉, Node.ELEMENT_NODE인 것이다.

element는 HTML에서 태그로 적은 노드들을 지칭한다. 예를 들어 <html>, <div>, <title>과 같은 태그로

DOM 프로퍼티

node에만 있는 dom 프로퍼티와 element에만 있는 dom 프로퍼티를 구분할 줄 알아야 한다.
다음 node의 프로퍼티들은 node나 NodeList라고 한다.


정리

Element와 Node의 차이점을 잘 이해하고, 적절한 때에 적절한 것에 접근하면 되는 것 같다. 예를 들자면, 현재 element의 parent로 넘어가서 sibling element에 접근해야 했다. 이 때, parentNode로 parent를 가져오려고 했을 때, 내가 의도한 바를 이루지 못했었다. element로 넘어가려면 parentElement를 했어야 하는데, 그러지 못한 것이었다. 이제 Node와 Element의 차이점을 알았으니, 파싱할때나 바닐라로 프로젝트할 시에 좀 더 삽질을 덜 할 수 있을 것이라고 믿는다.

productExampleElement.parseElement.nextElementSibling;

참고

What, exactly, is the DOM? - Ire Aderinokun
What's the Difference between DOM Node and Element?
profile
yejineee

profile
기록과 정리하는것을 계속해서 하려고 노력중이에요 😊

0개의 댓글