HTML / XML 문서는 브라우저 안에서 DOM 트리로 표현됩니다.

  • 태그는 요소 노드가 되고 트리 구조를 형성합니다.
  • 문자는 텍스트 노드가 됩니다.
  • 이 외에 HTML 내의 모든 것은 DOM을 구성합니다. 심지어 주석까지도 말입니다.

HTML 안의 모든 것들은 (심지어 그것은 주석이더라도) 노드이고, 이 노드들이 모이고 서로 연결되어 DOM을 구성하고 있습니다.

 

노드의 종류

노드 타입은 총 12가지인데, 실무에서 주로 다음 네 가지 노드를 다룹니다.

  1. DOM의 '진입점'이 되는 문서(document) 노드
  2. HTML 태그에서 만들어지며, DOM 트리를 구성하는 블록인 요소 노드(element node)
  3. 텍스트를 포함하는 텍스트 노드(text node)
  4. 화면에 보이지는 않지만, 정보를 기록하고 자바스크립트를 사용해 이 정보를 DOM으로부터 읽을 수 있는 주석(comment) 노드

노드의 탐색 관련 프로퍼티들

1. childNodes

childNodes 는 바로 아래의 자식 요소를 나타내며, 텍스트 노드를 포함한 모든 자식 노드를 담고 있습니다.

<html>
<body>
  <div>시작</div>

  <ul>
    <li>항목</li>
  </ul>

  <div>끝</div>

  <script>
    for (let i = 0; i < document.body.childNodes.length; i++) {
      alert(document.body.childNodes[i]); // Text, DIV, Text, UL, ... , SCRIPT
    }
  </script>
  ...추가 내용...
</body>
</html>

마지막으로 <script>가 출력되며, <script> 아래 더 많은 내용(...추가 내용...)이 있지만, 스크립트 실행 시점에는 브라우저가 추가 내용은 읽지 못한 상태이기 때문에 스크립트 역시 추가 내용을 보지 못합니다.

 

2. firstChild, lastChild

firstChild와 lastChild 프로퍼티를 이용하면 첫 번째, 마지막 자식 노드에 빠르게 접근할 수 있습니다.

elem.childNodes[0] === elem.firstChild
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild

 

 

위에서 살펴보았던 childNodes는 마치 배열 같아 보입니다. 하지만 childNodes는 배열이 아닌 반복 가능한 유사 배열 객체인 컬렉션(collection)입니다. childNodes는 컬렉션이기 때문에 다음과 같은 특징을 가집니다.

 

HTML Collection의 특징

1. for .. of 를 사용할 수 있습니다.

for (let node of document.body.childNodes) {
  alert(node); // 컬렉션 내의 모든 노드를 보여줍니다.
}

이터러블이기 때문에 Symbol.iterator 프로퍼티가 구현되어 있어서 for .. of 를 사용하는 것이 가능합니다.

 

2. 배열이 아니기 때문에 배열 메서드를 쓸 수 없습니다.

alert(document.body.childNodes.forEach); // undefined(forEach 메서드가 없습니다.)

만약 컬렉션에 배열 메서드를 사용하고 싶다면 Array.from을 적용하면 됩니다.

alert(Array.from(document.body.childNodes).forEach); // function

3. DOM 컬렉션은 살아있습니다. 즉 elem.childNodes를 참조하고 있는 도중에 DOM에 새로운 노드가 추가되거나 삭제되면, 변경사항이 컬렉션에도 자동으로 반영됩니다.

 

parentNode, childNodes, firstChild, lastChild 등 노드의 탐색 관련 프로퍼티는 모든 종류의 노드를 참조합니다. 예를 들어 childNodes를 이용하면 텍스트 노드, 요소 노드, 심지어 주석 노드까지 참조할 수 있습니다.

하지만 실무에서 텍스트 노드나 주석 노드는 잘 다루지 않습니다. 주로 DOM 요소 노드를 조작하는 작업이 대다수입니다.

그렇다면 텍스트 노드, 주석 노드를 제외한 채 DOM 요소 노드만을 조작할 수 있는 방법은 없을까요?

물론 있습니다.

 

DOM 요소 노드 탐색은 다음과 같이 이루어집니다.

  • children 프로퍼티 : 해당 요소의 자식 노드 중 요소 노드만을 가리킵니다.
  • firstElementChild, lastElementChild 프로퍼티 : 각각 첫 번째 자식 요소 노드와 마지막 자식 요소 노드를 가리킵니다.
  • previousElementSibling, nextElementSibling : 형제 요소 노드를 가리킵니다.
  • parentElement : 부모 요소 노드를 가리킵니다.
<html>
<body>
  <div>시작</div>

  <ul>
    <li>항목</li>
  </ul>

  <div>끝</div>

  <script>
    for (let elem of document.body.children) {
      alert(elem); // DIV, UL, DIV, SCRIPT
    }
  </script>
  ...
</body>
</html>

childNodes를 children으로 대체한 후 코드를 실행해본 결과 요소 노드만 출력되는 것을 알 수 있습니다.

 

'프로그래밍 언어 > JavaScript' 카테고리의 다른 글

Generator  (0) 2020.11.23
JavaScript와 Iterator  (0) 2020.11.23
DOM, CSSOM, BOM은 무엇일가?  (0) 2020.11.22
자바스크립트 모듈(Module)  (0) 2020.11.21
sort 함수를 이용한 정렬  (0) 2020.11.09
복사했습니다!