DOM Node와 Element

률루랄라·2022년 6월 28일
0
post-thumbnail

시작은 React reconciliation, 그 전에는 React18에 적용된 Suspense, useTransition 등에 대한 궁금증에서부터였다. 관련 글을 읽다보니 자주 나오는 개념인 DOM node, element 등에 대한 이해도를 높이고자 정리하는 글


DOM Node와 Element의 차이

Document Object Model, DOM, 은 HTML 혹은 XML 문서를 각 노드가 문서의 객체인 트리 구조로서 처리하기 위한 interface이다. DOM은 tree를 query (불러오기), 구조와 스타일을 변경하기 위한 여러 메소드들을 제공하기도 한다.

DOM은 또한 element라는 단어를 사용한다: node와 상당히 비슷하다. 그럼 두개는 무엇이 다른지 알아보자

1. DOM Node

node와 element의 차이를 알아보기 위해서 node가 무엇인지 알아보는게 중요하다.

더 큰 관점에서 보면 DOM document는 노드 계층으로 구성된다. 각 노드는 부모와 자식 혹은 각각 가질 수 있다. 다음 HTML 문서를 살펴보자

<!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은 다음과 같은 계층으로 표현이 가능하다.

ㄴ DOCTYPE: html
ㄴ HTML
	ㄴHEAD
    	ㄴTITLE
        	ㄴ#text: My Page
	ㄴBODY
    	ㄴ#comment: Page Body
        ㄴH2
        	ㄴtext: My Page
        ㄴP id="content"
        	ㄴ#text: Thank you for visiting my web page!

<html><head> and <body> node들을 자식으로 가지고 있는 document tree의 node이다.

<body> 또한 세개의 자식을 갖는 노드다. <!-- Page Body -->, heading <h2>, 그리고 paragraph <p>. <body> node의 부모는 <html> node다.

HTML document의 tag들은 노드를 대표한다. 더 흥미로운건 text 또한 노드이다. paragraph node <p> 는 text node "Thank you for visiting my web page!"를 자식으로 갖는다.

1.1 Node Types

DOM Node 인터페이스를 살펴보면 Node.nodeType 속성으로 노드의 타입을 구분할 수 있다.

Node.nodeType는 노드의 타입을 나타내는 다음의 값들이 있다.

  • Node.ELEMENT_NODE
  • Node.ATTRIBUTE_NODE
  • Node.TEXT_NODE
  • Node.CDATA_SECTION_NODE
  • Node.PROCESSING_INSTRUCTION_NODE
  • Node.COMMENT_NODE
  • Node.DOCUMENT_NODE
  • Node.DOCUMENT_TYPE_NODE
  • Node.DOCUMENT_FRAGMENT_NODE
  • Node.NOTATION_NODE

위 상수들은 노드 유형을 의미 있게 나타낸다: 예를 들면, Node.ELEMENT_NODE은 element node를 나타낸다.

예를 들어, paragraph node를 선택하고 선택된 노드의 타입을 살펴보자

const paragraph = document.querySelector('p');
paragraph.nodeType === Node.ELEMENT_NODE; // => true

예상대로 paragraph.nodeType은 paragraph가 element인 것을 알 수 있듯, Node.ELEMENT_NODE값을 가지고 있다.

paragraph는 또한 text node를 가지고 있다.

const paragraph = document.querySelector('p');
const firstChild = paragraph.childNodes[0];
firstChild.nodeType === Node.TEXT_NODE; // => true

또한 노드 타입에는 노드의 전체 document tree를 나타내는 Node.DOCUMENT_NODE 타입이 있다.

document.nodeType === Node.DOCUMENT_NODE; // => true

2. DOM Element

DOM Node가 무엇인지 잘 파악했으니 element와 구분점을 알아보자.

node에 대해 이해가 높다면 답은 명확하다: element은 Node.ELEMENT_NODE 라는 특정 타입의 노드이다.

간단하게 element는 HTML의 tag를 사용해 작성된 node라고 볼 수 있다. <html>, <head>, <title>, <body>, <h2> 등 모두 tag로 대변될 수 있기 때문에 element이다.

하지만 document type, comment, text 노드는 모두 tag로 작성되지 않았기 때문에 element가 아니다.

Node는 node의 constructor이고 HTMLElement는 Javascript DOM에서 element의 constructor이다. paragraph은 node이면서 element이기에 NodeHTMLElement의 instance다.

const paragraph = document.querySelector('p');
paragraph instanceof Node;        // => true
paragraph instanceof HTMLElement; // => true

element는 node의 subtype으로도 볼 수 있다: 고양이(element)와 동물(node)의 관계


3. DOM 속성: nodes and elements

node와 element의 구분을 차치하고, 오직 node 혹은 오직 element를 위한 DOM 속성들을 구분해볼 필요가 있다.

다음 Node 타입의 속성은 Node 혹은 NodeList로 평가된다.

node.parentNode; // Node or null
node.firstChild; // Node or null
node.lastChild;  // Node or null
node.childNodes; // NodeList

하지만 다음 속성들은 element 혹은 element collection(HTMLCollection)이다.

node.parentElement; // HTMLElement or null
node.children;      // HTMLCollection

node.childNodesnode.children 모두 children list를 반환하는데 왜 구분이 되어 있을까? 다음 예제 코드로 살펴보자

<p>
  <b>Thank you</b> for visiting my web page!
</p>

그 후 paragraph의 childNodeschildren을 살펴보면,

const paragraph = document.querySelector('p');
paragraph.childNodes; // NodeList:       [HTMLElement, Text]
paragraph.children;   // HTMLCollection: [HTMLElement]

paragraph.childNodes collection은 2개의 노드를 갖는다: bold element인 <b>Thank you</b>와 text node인 for visiting my web page!

하지만 paragraph.children collection은 bold element인 <b>Thank you</b>만 가지고있다. paragraph.children은 오직 element만 가지고 있을 수 있기 때문에 타입이 element(Node.ELEMENT_NODE)가 아닌 text 타입(Node.TEXT_NODE)를 갖는 text node는 포함되지 않는다.


4. 정리

DOM document는 노드 의 계층적 collection이다. 각 node는 부모, 자식 혹은 둘다 가질 수 있다.
즉 HTML의 계층을 표현할 수 있는 모든것은 다 Node다.

element은 Node.ELEMENT_NODE 라는 특정 타입의 노드로 HTML 문서의 tag를 사용해 작성된 node다.
Node는 element를 포함한다: 동물(Node)과 고양이(element)의 관계. 또한 Node이면서 element인 경우도 있다: paragraph.

다만, Document node (Node.DOCUMENT_NODE)은 절대 부모를 가질 수 없다.

profile
💻 소프트웨어 엔지니어를 꿈꾸는 개발 신생아👶

0개의 댓글