JavaScript 입문 | 문서 객체 모델 | 노드로의 접근

노드로의 접근

HTML 문서에서 HTML DOM 노드에 접근하는 방법은 다음과 같다.

  1. getElementsByTagName() 메소드를 이용하는 방법
  2. 노드 간의 관계를 이용하여 접근하는 방법

getElementsByTagName() 메소드를 이용하는 방법

getElementsByTagName() 메소드는 특정 태그 이름을 가지는 모든 요소를 노드 리스트의 형태로 반환한다.
따라서 이 메소드가 반환하는 노드 리스트를 이용하면 원하는 노드에 접근할 수 있다.

HTML DOM에서 노드 간의 관계는 다음과 같은 프로퍼티로 정의된다.

  1. parentNode : 부모 노드
  2. childNodes : 자식 노드 리스트
  3. firstChild : 첫 번째 자식 노드
  4. lastChild : 마지막 자식 노드
  5. nextSibling : 다음 형제 노드
  6. previousSibling : 이전 형제 노드

위와 같은 프로퍼티를 이용하여 원하는 노드에 손쉽게 접근할 수 있다.

노드에 대한 정보

노드에 대한 정보는 다음과 같은 프로퍼티를 통해 접근할 수 있다.

  1. nodeName
  2. nodeValue
  3. nodeType

이 프로퍼티들은 특별히 다른 인터페이스를 이용하지 않고도, 해당 노드의 정보에 직접 접근할 수 있는 방법을 제공한다.

nodeName

nodeName 프로퍼티는 노드 고유의 이름을 저장하므로, 수정할 수 없는 읽기 전용 프로퍼티이다.

요소 노드의 nodeName 프로퍼티는 언제나 해당 HTML 요소의 태그 이름을 대문자로 저장한다.

노드 프로퍼티 값
문서 노드(document node) #document
요소 노드(element node) 태그 이름 (영문자로 대문자)
속성 노드(attribute node) 속성 이름
텍스트 노드(text node) #text
// HTML 문서의 모든 자식 노드 중에서 두 번째 노드의 이름을 선택함.
document.getElementById("document").innerHTML = document.childNodes[1].nodeName;           // HTML
 
// html 노드의 모든 자식 노드 중에서 첫 번째 노드의 이름을 선택함.
document.getElementById("html").innerHTML = document.childNodes[1].childNodes[0].nodeName; // HEAD

위의 예제에서 HTML 문서의 첫 번째 자식 노드는 <!DOCTYPE html>이며, 두 번째 자식 노드는 <html>이다. 또한, <html> 노드의 첫 번째 자식 노드는 <head> 이며, 세 번째 자식 노드는 <body>이다.

nodeValue

nodeValue 프로퍼티는 노드의 값을 저장한다.

노드 프로퍼티 값
요소 노드(element node) undefined
속성 노드(attribute node) 해당 속성의 속성값
텍스트 노드(text node) 해당 텍스트 문자열
// 아이디가 "heading"인 요소의 첫 번째 자식 노드의 노드값을 선택함.
var headingText = document.getElementById("heading").firstChild.nodeValue;
 
document.getElementById("text1").innerHTML = headingText;
document.getElementById("text1").firstChild.nodeValue = headingText;

지금까지 innerHTML 프로퍼티를 사용하여 손쉽게 HTML 요소의 내용(content)에 접근하거나, 내용을 변경할 수 있었다.
이러한 innerHTML 프로퍼티 대신에 firstChild.nodeValue를 사용해도 같은 결과를 얻을 수 있다.

nodeType

nodeType 프로퍼티는 노드 고유의 타입을 저장하므로, 수정할 수 없는 읽기 전용 프로퍼티이다.

대표적인 HTML 노드별 nodeType 프로퍼티 값은 다음과 같다.

노드 프로퍼티 값
요소 노드(element node) 1
속성 노드(attribute node) 2
텍스트 노드(text node) 3
주석 노드(comment node) 8
문서 노드(document node) 9
// 아이디가 "heading"인 요소의 첫 번째 자식 노드의 타입을 선택함.
var headingType = document.getElementById("heading").firstChild.nodeType;
 
document.getElementById("head").innerHTML = headingType;           // 3
document.getElementById("document").innerHTML = document.nodeType; // 9

빈 텍스트 노드의 처리

현재 대부분의 주요 웹 브라우저는 모두 W3C DOM 모델을 지원하지만, 그 처리 방식에 있어 약간씩의 차이가 있다.
그중에서도 가장 큰 차이점은 띄어쓰기와 줄 바꿈을 처리하는 방식이다.

파이어폭스나 기타 브라우저들은 띄어쓰기나 줄 바꿈을 텍스트 노드(text node)로 취급한다.
하지만 익스플로러는 띄어쓰기나 줄 바꿈을 텍스트 노드로 취급하지 않는다.

따라서 자식 노드나 형제 노드를 이용하여 원하는 노드에 접근하려고 하면 브라우저 간에 차이가 발생하게 된다.
이 차이를 없애는 가장 손쉬운 방법은 nodeType 프로퍼티를 사용하여 선택된 요소의 타입을 검사하는 것이다.

var lastNode;
function findLastChild(parentNode) {
    lastNode = parentNode.lastChild;
    while (lastNode.nodeType != 1) {
        lastNode = lastNode.previousSibling;
    }
}
function printLastChild() {
    var parentNode = document.getElementById("parentNode");
    findLastChild(parentNode);
    document.getElementById("nodename").innerHTML = lastNode.nodeName;
}

위의 예제에서 마지막 자식 노드를 찾은 후에, 찾은 노드의 타입이 요소 노드가 아니면 그 앞의 노드를 다시 검사한다.
이 방식을 사용하면 모든 브라우저에서 마지막 자식 노드로 같은 요소 노드를 선택할 수 있게 된다.