소년코딩

Node 인터페이스

HTML의 각 마크업은 트리에서 노드로 표현된다.

  • DOCUMENT_NODE                            (예: window.document)
  • ELEMENT_NODE                                (예: <body>, <a>, <p>, <script>, <style>, <html>, <h1>,,,)
  • ATTRIBUTE_NODE                             (예: class='modal')
  • TEXT_NODE                                        (예: 줄바꿈과 공백등을 포함한 HTML 문서 내의 텍스트)
  • DOCUMENT_FRAGMENT_NODE     (예: document.createDocumentFragment())
  • DOCUMENT_TYPE_NODE                (예: <!DOCTYPE html>)

총 12가지 노드 타입이 있다.

 

DOM에는 Node라는 인터페이스가 있는데 DOM에 존재하는 모든 노드 타입은 이 인터페이스를 구현한다.

자바스크립트의 노드 타입은 모두 Node를 상속하므로 모든 노드 타입에서 같은 기본 프로퍼티와 메서드를 공유한다.

 

모든 노드 타입은 12가지 숫자형 상수중 하나이다.

for (var key in Node) {
    console.log(key, ' = ', Node[key]);
};

/**
ELEMENT_NODE  =  1
ATTRIBUTE_NODE  =  2
TEXT_NODE  =  3
CDATA_SECTION_NODE  =  4
ENTITY_REFERENCE_NODE  =  5
ENTITY_NODE  =  6
PROCESSING_INSTRUCTION_NODE  =  7
COMMENT_NODE  =  8
DOCUMENT_NODE  =  9
DOCUMENT_TYPE_NODE  =  10
DOCUMENT_FRAGMENT_NODE  =  11
NOTATION_NODE  =  12
DOCUMENT_POSITION_DISCONNECTED  =  1
DOCUMENT_POSITION_PRECEDING  =  2
DOCUMENT_POSITION_FOLLOWING  =  4
DOCUMENT_POSITION_CONTAINS  =  8
DOCUMENT_POSITION_CONTAINED_BY  =  16
 
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC  =  32
**/

 

노드 타입을 알아보려면 다음과 같이 상수와 비교하면 된다.

if (someNode.nodeType == 1) {
        console.log('this is element.');
}

Node 객체로부터 상속받은 하위 노드 객체

각각의 노드 객체는 Node로부터 프로퍼티와 메서드를 상속받는다.

또한 Node객체 역시 객체이므로 Object.prototype을 상속 받는다.

  • Object < Node < Element < HTMLElement < (e.g, HTML * Element)
  • Object < Node < Attr
  • Object < Node < CharacterData < Text
  • Object < Node < Document < HTMLDocument
  • Object < Node < DocumentFragement

노드의 주요 프로퍼티와 메서드

  • nodeType
  • nodeName
  • nodeValue
  • childNodes
  • parentNode
  • firstChild
  • lastChild
  • nextSibiling
  • previousSibling
  • appendChild()
  • cloneNode()
  • compareDocumentPosotion()
  • contains()
  • hasChildNodes()
  • insertBefore()
  • isEqualNode()
  • removeChild()
  • replaceChild()

nodeName, nodeValue 프로퍼티

nodeName과 nodeValue 프로퍼티는 해당 노드의 정보를 제공한다.

프로퍼티 값은 노드 타입에 따라 완전히 다르므로 이 값을 사용하기 전에는 항상 노드 타입을 테스트해주는게 좋다.

if (someNode.nodeType == 1 /* == Node.ELEMENT_NODE */) {
    value = someNode.nodeName;    // 요소 노드라면, 요소의 태그 이름
}

노드가 요소 노드라면 nodeName은 항상 요소 태그의 이름과 일치하며, nodeValue는 항상 null이다.


노드 사이의 관계

모든 노드는 다른 노드와 관계가 있다.

이런 관계는 문서 트리를 가족 계보처럼 생각해서 가족 관계로 설명하곤 한다.

HTML에서

<body>요소는 <html>요소의 자식이며, 

<html>요소는 <body>요소의 부모이다.

<head>요소는 <body>요소의 형제로 간주하는데, 두 요소가 같은 <html>요소를 부모로 공유하기 때문이다.

각 노드에는 자식노드를 가리키는 childNodes 프로퍼티가 있는데 이 프로퍼티에는 NodeList가 저장된다.

  • NodeList 객체는 배열 비슷한 객체인데, 노드를 순서 있는 목록으로 저장하여 위치 기반으로 접근 할 수있다.
  • NodeList 객체는 length 프로퍼티가 있고 저장된 데이터를 대괄호 표기법을고 접근 할 수있는 유사 배열 객체다.
  • NodeList 객체는 DOM 구조에대한 쿼리 결과이며, 문서가 바뀌면 NodeList 객체에도 자동으로 반영되는 '살아 있는 객체'다.
var firstChild = someNode.childNodes[0];         // 대괄호 표기법 방식
var secondChild = someNode.childNodes.item(1);   // item() 메서드 방식
var count = someNode.length;                     // 자식 노드의 개수
// '호출 당시' NodeList에 담긴 노드 숫자 => 라이브 상태 이므로 바뀔 수 있다.

parentNode

각 노드에는 문서 트리에서 부모를 가리키는 parentNode 프로퍼가 있다.

childNodes 목록에 포함된 노드는 모두 부모가 같으므로 각각의 parentNode 프로퍼티는 같은 노드를 가리킨다.

또한 childNodes 목록의 각 노드는 형제 관계다.

같은 목록에 잇는 노드 사이를 previousSlibing 및 nextSlibing 프로퍼티로 이동할 수 있다.

if(someNode.nextSibling === null) {
     console.log("Last node in the parent's childNodes list.");
} else {
     console.log('First node in the parent's childNodes list.');
} 

부모 노드의 첫번 째, 마지막 자식 노드 관계를 가리키는 다른 관계도 존재한다.

firstChild와 lastChild 프로퍼티는 각각 childNodes 목록에서 첫 번쨰와 마지막 노드를 가리킨다.

노드사이의관계


노드 확인

  • hasChildNodes()라는 편리한 메서드가 있다.
  • hasChildNodes() 메서드 : 노드에 자식 노드가 있다면 true를 반환한다.
  • contains() 메서드 : 주어진 노드가 다른 노드의 자식이라면 true를 반환한다.
  • isEqualNode() 메서드 : 같은 노드라면 true를 반환한다.

노드 조작

  • appendChild() : childNodes 목록 마지막에 노드를 추가한다.

이 메서드를 실행하며 새로 추가한 노드, 부모 노드, childNodes 목록에 포함된 이전의 마지막 자식노드에서 모든 관계가 업데이트된다.

업데이트가 완료되면 appendChild()는 새로 추가한 노드를 반환한다.

var returnedNode = someNode.appednChild(newNode);

console.log(returnedNode == newNode);   // true
console.log(someNode.lastChild == newNode);   // true

 

  • insertBefore() : 삽입할 노드와 기준 노드 두 가지를 매개변수로 받는다.

삽입한 노드는 기준 노드의 이전 형제가 되며 이동이 끝나면 메서드는 삽입한 노드를 반환한다. 기준 노드가 null이라면 insertBefore()는 appendChild()와 똑같이 동작한다.

// 마지막 자식으로 삽입
returnedNode = someNode.insertBefore(newNode, null);
console.log(newNode == someNode.lastChild);   // true
 
// 첫 자식으로 삽입
returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
console.log(returnedNode == newNode);   // true
console.log(newNode == someNode.firstChild);   // true
 
// 마지막 자식 앞에 삽입
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
cxonsole.log(newNode == someNode.childNodes[someNode.childNodes.length - 2]);

appendChild()와 insertBefore()은 모두 기존의 노드를 제거하는 일 없이 삽입을 한다.

반면 replacChild() 메서드는 기존 노드를 교체한다.

 

  • replaceChild() : 매개 변수로 삽입할 노드(A)와 교체할 노드(B) 두개를 받아서 B를 문서 트리에서 제거해 반환하며,  B가 있던 자리에 A를 대신 삽입한다.
// 마지막 자식으로 삽입
returnedNode = someNode.insertBefore(newNode, null);
console.log(newNode == someNode.lastChild);   // true
 
// 첫 자식으로 삽입
returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
console.log(returnedNode == newNode);   // true
console.log(newNode == someNode.firstChild);   // true
 
// 마지막 자식 앞에 삽입
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
cxonsole.log(newNode == someNode.childNodes[someNode.childNodes.length - 2]);

 

  • 노드를 제거할 때는 removeChild() 메서드를 사용한다.
// 첫 번째 자식을 제거
var formerFirstChild = someNode.removeChild(someNode.firstChild);
 
// 두 번째 자식을 제거
var formerLastChild = someNode.removeChild(someNode.lastChild);

기타 메서드

cloneNode() : 자신을 호출한 노드의 복제본을 생성한다.

cloneNode() 메서드는 매개변수를 하나 받는데 이는 자손 노드까지 복제할지 나타내는 불리언 이다.

true를 넘기면 자손 노드 전체를 복제하며, false를 넘기면 해당 노드 하나만 복제한다..

복제된 노드를 반환하는데 이는 여전히 문서 소유이지만 부모 노드가 할당되지 않는다.


 

js

by 소년코딩

추천은 글쓴이에게 큰 도움이 됩니다.

악플보다 무서운 무플, 댓글은 블로그 운영에 큰 힘이됩니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기