DOM

2014. 12. 8. 15:03 나홀로스터디/JS For Web Dev


10장 DOM

이 포스팅은 "프론트엔드 개발자를 위한 자바스크립트(2013 인사이트, 한선용 옮김)"에서 발췌 요약한 것입니다.
 
- DOM을 노드의 계층 구조로 이해
- 다양한 노드타입
- 브라우저들 간의 비호환성을 우회하는 DOM 코딩



문서 객체 모델 DOM은 HTML과 XML 문서에 대한 애플리케이션 프로그래밍 인터페이스(API)다. 넷스케이프와 마이크로소프트에서 초기에 사용하던 동적 HTML을 계승한 DOM은 이제 진정으로 플랫폼과 언어에 독립적인 페이지 표현 및 조작 방법이 되었다.

DOM 레벨 1은 1998년 10월에 W3C 권고가 되었고 기본적인 문서구조와 쿼리 인터페이스를 제공한다.

※ 인터넷 익스플로러8 및 이전 버전에서는 DOM 객체를 COM 객체로 구현했다. 따라서 이들 객체는 네이티브 자바스크립트 객체와는 다른 방식으로 동작한다.

 

10.1 노드의 계층 구조
HTML과 XML 문서는 모두 DOM을 통해 노드의 계층 구조로 표현 가능하다. 노드 타입에는 여러가지가 있으며 각 노트 타입은 서로 다른 특징, 데이터, 메서드를 가지고 각 노드는 다른 노드와 관계가 있을 수도 있다. 이런 계층 구조를 생성하며 특정 노드에 뿌리(root)를 둔 트리 구조로 표현된다.

문서 요소는 문서의 최상위 요소로 문서 하나에 문서 요소 하나만 존재하며 다른 요소는 모두 이 안에 존재한다. HTML 페이지에서 문서 요소는 항상 <html> 요소이고 XML에서는 미리 지정된 문서 요소가 없으면 어떤 요소든 문서 요소가 될 수 있다.


10.1.1  Node 타입
Node 인터페이스는 자바스크립트에서 Node 타입으로 구현되며 인터넷 익스플로러를 제외한 모든 브라우저에서 Node 타입에 접근할 수 있다. 자바스크립트의 노드 타입은 모두 Node를 상속하므로 모든 노드 타입에서 같은 기본 프로퍼티와 메서드를 공유한다.
모든 노드에는 타입을 나타내는 nodeType 프로퍼티가 있고 노드 타입은 다음 12가지 숫자형 상수 중 하나이다

Node.ELEMENT_NODE(1)
Node.ARRTIBUTE_NODE(2)
Node.TEXT_NODE(3)
Node.CDATA_SECTION_NODE(4)
Node.ENTITY_REFERENCE_NODE(5)
Node.ENTITY_NODE(6)
Node.PROCESSING_INSTRUCTION_NODE(7)
Node.COMMENT_NODE(8)
Node.DOCUMENT_NODE(9)
Node.DOCUMENT_TYPE_NODE(10)
Node.DOCUMENT_FRANMENT_NODE(11)
Node.NOTATION_NODE(12)


nodeName, nodeValue 프로퍼티
nodeName과 nodeValue 프로퍼티는 해당 노드의 정보를 제공한다. 프로퍼티 값은 노드 타입에 따라 완전히 다르므로 이 값을 사용하기 전에 항상 노트 타입을 테스트하길 권장한다.

if (someNode.nodeType == 1){
  value = someNode.nodeName;  // 요소의 태그 이름
} 

노드가 요소라면 nodeName 값을 변수에 할당한다. 요소의 nodeName은 항상 요소의 태그 이름과 일치하며 nodeValue는 항상 null이다.

 

노드 사이의 관계
모든 노드는 다른 노드와 관계가 있다. 각 노드에는 childNodes 프로퍼티가 있는데 이 프로퍼티에는 NodeList가 저장된다. NodeList는 배열 비슷한 객체인데 노드를 순서 있는 목록으로 저장하여 위치 기반으로 접근할 수 있다. NodeList에 length 프로퍼티가 있고 저장된 데이터를 대괄호 표기법으로 접근할 수 있긴 하지만 NodeList는 Array의 인스턴스가 아니다. NodeList 객체는 사실 DOM 구조에 대한 쿼리 결과이며 문서가 바뀌면 NodeList 객체에도 자동으로 반영되어 '살아있는' 객체라고 부르기도 한다.

각 노드에는 문서 트리에서 부모를 가리키는 parentNode 프로퍼티가 있고 childNodes 목록의 각 노드는 형제 관계이다. 같은 목록에 있는 노드 사이를 previousSiblingnextSibling 프로퍼티로 이동할 수 있다. 그 외에 편리한 메서드로 hasChildNodes()가 있는데 이 메서드는 노드에 자식 노드가 있다면 true를 반환하며 매번 childNodes 목록에서 length를 호출하는 것보다 효과적이다.
ownerDocument 프로퍼티는 전체 문서를 표현하는 문서 노드에 대한 포인터이다.

※ 노트 타입이 모두 Node를 상속하긴 하지만 노드 타입이 모두 자식 노드를 가질 수 있는 건 아니다.


노드조작
노드 사이의 관계 포인터는 모두 읽기 전용이므로 노드를 조작하는 메서드는 따로 있다. 가장 자주 쓰이는 메서드는 appendChild()인데 이 메서드는 childNodes 목록에 노드를 추가하고 새로 추가한 노드, 부모 노드, childNodes 목록에 포함된 모든 관계 포인터가 업데이트 되면 appendChild()는 새로 추가한 노드를 반환한다.

한 노드를 childNodes 목록 마지막이 아니라 특정 위치로 옮겨야 할 때insertBefore() 메서드를 사용한다. insertBefore() 메서드는 삽입할 노드기준 노드 두 가지를 매개변수로 받는데 삽입한 노드는 기준 노드의 이전 형제가 되며 이동이 끝나면 메서드는 삽입한 노드를 반환한다. 기준 노드가 null 이라면 insertBefore()는 appendChild()와 똑같이 동작한다.

appendChild()와 insertBefore()는 모두 기존의 노드를 제거하는 일 없이 삽입하기만 하는 반면 replaceChild() 메서드는 기존 노드를 교체한다.  replaceChild() 메서드는 매개변수로 삽입할 노드(A)와 교체할 노드(B) 두 개를 받아서 B를 문서 트리에서 제거해 반환하며 B가 있던 자리에 A를 대신 삽입한다. replaceChild()로 노드를 삽입하면 B의 관계 포인터를 모두 A에 복사한다.

노드를 제거할 때removeChild() 메서드를 사용한다. 이 메서드는 제거할 노드 하나만 매개변수로 받는데 제거된 노드는 함수 값으로 반환된다.

이들 네가지 메서드는 모두 특정 노드의 자식에서만 동작하므로 parentNode 프로퍼티에 해당하는 부모 노드를 정확히 알아야 한다.

 

기타 메서드
cloneNode() 메서드는 자신을 호출한 노드의 복제본을 생성한다. cloneNode() 메서드는 매개변수를 하나 받는데 이는 자손 노드까지 복제할지 나타내는 불리언으로 true를 넘기면 자손 노드 전체를 복제하며 false를 넘기면 해당 노드 하나만 복제한다.복제된 노드는 appendChild()나 insertBefore(), replaceChild()를 통해 문서에 추가하기 전에는 트리 안에 존재하지 않는다.

※ cloneNode() 메서드는 이벤트 핸들러처럼 DOM 노드에 추가한 자바스크립트 프로퍼티는 복사하지 않는다. 이 메서드는 속성과 자식 노드만 복사하며 다른 것은 모두 사라진다. 인터넷 익스플로러에는 이벤트 핸들러까지 복제하는 버그가 있으므로 복제하기 전에 이벤트 핸들러를 모두 제거하길 권한다.


 

10.1.2 Document 타입
자바스크립트는 문서 노드를 Document 타입으로 표현한다. 브라우저에서 전체 HTML 페이지를 표현하는 문서 객체는 HTMLDocument의 인스턴스이며 HTMLDocument는 Document를 상속한다. document 객체는 window의 프로퍼티이므로 전역에서 접근할 수 있다.  Document 노드에는 다음 특징이 있다.

- nodeType은 9이다.
- nodeName은 "#document"이다.
- nodeValue는 null이다
- parentNode는 null이다
- ownerDocument는 null이다
- 자식 노드로 DocumentType(최대 1개) Element(최대 1개), Processing Instruction, Comment를 가질 수 있다.


Document 타입은 HTML 페이지 또는 XML 기반 문서를 표현하며 가장 자주 쓰이는 용도는 document 객체를 통한 HTMLDocument의 인스턴스이다.

※  파이어폭스와 사파리, 크롬, 오페라에서는 스크립트에서 Document 타입 생성자 및 프로토타입에 접근할 수 있다. 인터넷 익스플로러는 버전 9에서도 Document를 노출하지 않는다. HTMLDocument 타입 생성자 및 프로토타입은 인터넷 익스플로러 버전 8 이후 및 기타 브라우저에서 접근할 수 있다.



Document의 자식 노드
DOM 명세에서는 Document 노드가 자식으로 DocumentType, Element, ProcessingInstruction, Comment를 가질 수 있다고 명시하는데 그중 두 가지 자식 노드에는 단축 표기도 있다. 첫 번째는 documentElement 프로퍼티인데 이는 항상 HTML 페이지의 <html> 요소를 가리킨다.  childNodes 목록에는 항상 document 요소가 있지만 documentElement 프로퍼티는 해당 요소에 더 빨리 더 직접적으로 접근한다.

document 객체는 HTMLDocument 의 인스턴스이므로 <body> 요소를 직접적으로 가리키는 body 프로퍼티를 갖는다. 주요 브라우저는 모두 document.documentElementdocument.body를 둘 다 지원한다. Document가 가질 수 있는 또다른 자식 노드는 DocumentType이다. <!DOCTYPE> 태그는 문서의 다른 부분과는 별도의 엔티티로 간주하며 포함된 정보는 doctype 프로퍼티(브라우저에서는 document.doctype)를 통해 접근할 수 있지만 브라우저마다 document.doctype을 달리 지원하므로 유용하게 쓰기 어렵다.
<html> 요소 밖에 있는 주석은 기술적으로는 문서의 자식 노드이지만 브라우저마다 다르게 처리한다.


문서정보
document 객체는 HTMLDocument의 인스턴스이므로 표준 Document 객체에는 현재 불러드린 웹 페이지에 대한 프로퍼티를 갖는다. title 프로퍼티는 브라우저 창 또는 탭의 제목인 <title> 요소 텍스트가 들어 있다. 이 프로퍼티로 현재 페이지 제목을 읽을 수 있고 설정도 가능한데 title 프로퍼티의 값을 바꿔도 <title> 요소는 변함이 없다.


요소 위치
DOM 관련해서 가장 자주 하는 일은 특정 요소나 요소 그룹에 대한 참조를 얻는 일인데 document 객체에는 getElementById()getElementsByTagName() 두가지 메서드를 제공한다. getElementById() 메서드는 찾으려는 요소 ID를 매개변수로 받고 해당 요소를 찾아 반환하며 그런 ID 요소가 존재하지 않으면 null을 반환한다.
getElementByTagName() 메서드는 요소의 태그 이름을 매개변수로 받고 해당하는 요소가 담긴 NodeList를 반환한다.

var images = document.getElementByTagName("img"); 

HTMLCollection 객체는 images 변수에 저장되고 객체에 담긴 요소 숫자는 length 프로퍼티에 저장된다. HTMLCollection 객체에는 namedItem() 메서드도 있는데 이 메서드는 name 속성을 통해 컬렉션 데이터에 대한 참조를 얻는다. HTMLCollection 객체에서는 대괄호 표기법에 숫자형 색인과 문자형 색인을 모두 쓸수 있는데 숫자형 색인을 쓰면 이면에서 item()을 호출하고 문자열 색인을 쓰면 namedItem()을 호출한다.

※ 명세에서는 태그 이름이 대소문자를 구분하는 것으로 정의되어 있지만 getElementByTagName() 메서드는 기존의 HTML 페이지와 최대한 호환되게 하기 위해 대소문자를 구분하지 않는다. XHTML이나 XML페이지에서는 getElementByTagName() 메서드가 대소문자를 구분한다.

세번째 메서드는 HTMLDocument 타입에만 정의된 getElementByName()으로 name 속성 값이 주어진 문자열에 일치하는 요소를 반환한다. getElementByTagName()와 마찬가지로 getElementByName() 메서드 역시 HTMLCollection을 반환한다. name() 메서드는 항상 첫 번째 버튼만 가져오는데 name 속성이 모두 같기 때문이다.


특별한 컬렉션

document.anchors - name 속성이 있는 <a> 요소를 모두 가져온다
document.form - <form> 요소를 모두 가져온다. document.getElementsByTagName("form")과 같다
document.images - <img> 요소를 모두 가져온다. document.getElementsByTagName("img")와 같다.
document.links - href 속성이 있는 <a> 요소를 모두 가져온다.



문서에 쓰기
웹페이지에 출력을 직접 조작하는 기능을 담당하는 메서드는 write(). writeIn(), open(), close() 네 가지다. write(), writeIn() 메서드는 문자열을 매개변수로 받는데 write()는 넘겨 받은 텍스트를 그대로 추가하고, writeIn()은 줄바꿈 문자(\n)를 마지막에 추가한다.

※ XHTML 문서에서는 문서에 쓰는 기능을 지원하지 않는다. application/xml_xhtml 마임 타입으로 전송되는 페이지에서는 이 메서드가 동작하지 않는다.

 


10.1.3 Element 타입
Element 타입은 XML/HTML 요소를 표현하며 이를 통해 태그 이름이나 자식, 속성 같은 정보에 접근 가능하다.

nodeType은 1이다.
nodeName은 요소의 태그 이름이다.
nodeValue는 null이다.
parentNode는 Document 또는 Element이다.
자식 노드로 Element나 Text, Comment, ProcessingInstruction, CDATA Section, EntityRefernce를 가질수 있다.

요소의 태그 이름은 nodeName 프로퍼티나 tagName 프로퍼티로 얻을수 있고 두 프로퍼티는 같은 값을 반환하는데 후자가 더 직관적이다.
HTML에서 tagName을 사용하면 태그 이름은 항상 대문자로 반환되므로 element.tagName.toLowerCase()를 사용하는 것이 안전하다

※ Element 타입 생성자와 프로토타입은 인터넷 익스플로러 버전 8을 포함해 모든 최신 브라우저에서 스크립트를 통해 접근할 수 있다. 사파리 버전2 미만이나 오페라 버전 8미만 같은 오래된 브라우저는 Element 타입 생성자를 스크립트에 노출하지 않는다.


HTML 요소
HTML요소는 모두 HTMLElement 타입을 통해 표현된다. HTMLElement는 Element를 직접적으로 상속하며 몇가지 프로퍼티가 추가되는데 각 프로퍼티는 모든 HTML 요소에서 사용가능한 표준 속성중 하나를 나타낸다.

id - 요소의 고유한 식별자
title - 요소에 대한 추가 정보, 일반적으로 툴팁으로 표현된다.
lang -  요소 콘텐츠의 언어 코드
dir - 언어의 표기 방향
className -  요소의 CSS 클래스인 class 속성을 나타냄, class가 ECMAScript의 예약어이기 때문에 class라고 부르지 못함

각 프로퍼티는 속성 값을 읽는 용도로도, 값을 설정하는 용도로도 사용한다.


속성얻기
속성에 대한 DOM 메서드는 getAttribute(), setAttribute(), removeAttribute() 이다.
getAttribute()에는 속성 이름을 그대로 써야 하고 주어진 속성이 존재하지 않으면 항상 null을 반환한다. getAttribute() 메서드는 HTML 언어에 공식적으로 포함되지 않는 커스텀 속성의 값을 가져오는 데도 쓸 수 있다.
요소 속성은 모두 DOM 요소 객체의 프로퍼티를 통해서도 접근할 수 있다. HTMLElement에 정의된 다섯 가지 프로퍼티는 해당 속성과 직접 연결되며, 그 외에도 브라우저에서 인식하는(커스텀이 아닌) 속성은 모두 객체 프로퍼티로 추가된다.

두번째 속성은 onclick 같은 이벤트 핸들러 속성인데 요소의 onclick 속성은 자바스크립트 코드이며 getAttribute()는 해당 코드 문자열을 반환한다. 반면 onclick 프로퍼티는 이벤트 처리 프로퍼티가 자신에게 할당된 함수에 접근할 수 있기 때문에 자바스크립트 함수를 반환하고 해당 속성이 없을 때는 null을 반환한다.
이런 차이로 개발자들은 DOM을 다룰 때 객체 프로퍼티를 사용하고 getAttribute() 메서드는 주로 커스텀 속성의 값을 가져올 때 사용한다.


속성 설정
getAttribute()의 형제 메서드인 setAttribute()는 속성 이름과 설정할 값 두 가지를 매개변수로 받는다. 속성이 존재하면 setAttribute()는 해당 속성의 값을 교체하며 존재하지 않을 때는 속성을 새로 생성하고 값을 설정한다. setAttribute() 메서드는 HTML 속성과 커스텀 속성을 같은 방식으로 다룬다. 속성은 모두 프로퍼티이므로 프로퍼티에 직접 할당하는 것은 속성 값을 설정하는것과 마찬가지다.
커스텀 프로퍼티를 추가하면 대부분의 브라우저에서 요소 속성이 되지 않지만 인터넷 익스플로러에서는 가능하다.

※ 인터넷 익스플로러 7 및 이전 버전에서는 setAttribute()가 좀 이상하게 동작한다. class나 style속성을 설정해도 효과가 없으며 setAttribute()로 이벤트 핸들로 프로퍼티를 설정하려 해도 아무 효과가 없다. 이 문제가 인터넷 익스플로러8에서 고쳐지긴 했지만 이들 속성을 설정할 때는 항상 프로퍼티를 이요하는 편이 좋다.


removeAttribute() 메서드는 속성의 값만 지우는 것이 아니라 요소에서 속성을 완전히 제거한다.

※ 인터넷 익스플로러 6 이전버전은 지원하지 않는다.

 

attributes 프로퍼티
Element 타입은 DOM 노드 타입 중에서 attribute 프로퍼티를 갖는 유일한 타입이다. attribute 프로퍼티에는 "살아있는" 컬렉션(NodeList와 비슷한) NamedNodeMap이 저장된다. 요소의 속성은 모두 Attr 노드로 표현되며 각 Attr 노드는 NameNodeMap객체에 저장된다.

getNamedItem(name) - nodeName 프로퍼티가 name인 노드를 반환한다.
removeNamedItem(name) - nodeName 프로퍼티가 name인 노드를 목록에서 제거한다.
setNamedItem(node) - node를 목록에 추가하고 nodeName 프로퍼티에 따라 색인한다
item(pos) - 인덱스가 pos인 노드를 반환한다.

attributes 프로퍼티 안의 각 노드는 nodeName이 속성 이름이며 nodeValue는 속성 값이다.

element.attributes.getNamedItem("id").nodeValue
element.attributes["id"].nodeValue; 

removeNamedItem() 메서드는 요소의 removeAttribute() 메서드와 마찬가지로 주어진 이름의 속성을 제거한다.
setNamedItem() 메서드는 속성 노드를 넘겨 요소에 새 속성을 추가하는 메서드인데 속성 메서드보다는 getAttribute(). removeAttribute(), setAttribute() 메서드가 더 많이 쓰인다.


요소 생성
document.ceateElement() 메서드를 통해 새 요소를 생성할 수 있다. 이 메서드는 생성할 요소의 태그 이름 하나만 매개변수로 받는다. createElement() 메서드는 새 요소를 생성하고 ownerDocument 프로퍼티를 설정한다.

인터넷 익스플로러7 및 이전 버전에서 동적으로 요소를 생성할 때 발생하는 문제점은 다음과 같다.

- 동적으로 생성한 <iframe> 요소의 name 속성을 설정할 수 없다.
- 동적으로 생성한 <input> 요소는 폼의 reset() 메서드로 리셋되지 않는다.
- 동적으로 생성한 <button> 요소에 타입 속성 "reset"이 있어도 이 버튼은 폼을 리셋하지 못한다.
- 동적으로 생성한 라디오 버튼은 같은 name 속성의 라디오 버튼과 연결되지 않는다.

인터넷 익스플로러7 및 이전 버전의 이런 문제는 createElement()에 완전한 HTML 태그를 넘겨서 해결 가능하다


요소의 자식
요소는 자식 요소나 자손 요소를 가질 수 있으며 그 숫자에는 제한이 없다. 특정 태그 이름의 자식 노드나 자손 요소를 가져올 때는 getElementByTagName() 메서드도 사용한다. 이 메서드를 요소에서 호출하면 document에서 호출한 것과 똑같이 동작하지만 해당 요소에서 검색을 시작한다는 점만 다르며 따라서 자손 요소만 반환한다.



10.1.4 Text 타입
Text 노드는 Text 타입으로 표현된다. 이 노드는 평범한 텍스트가 포함되고 글자 그대로 사용되며 이스케이프된 HTML 문자는 포함할 수 있지만 HTML 코드는 포함할 수 없다.

- nodeType은 3이다.
- nodeName은 "#text"이다.
- nodeValue는 노드에 포함된 텍스트이다
- parentNode는 Element 이다.
- 자식 노드를 가질 수 없다.

Text 노드에 포함된 텍스트는 nodeValue 프로퍼티나 data 프로퍼티로 가져올 수 있으며 두 프로퍼티에는 같은 값이 저장되고 nodeValue나 data 둘 중 하나를 바꾸면 노드에 반영된다.

- appendData(text) - 노드 마지막에 text를 추가한다.
- deleteData(offset, count) - offset부터 count 만큼 삭제한다.
- insetDate(offset, text) - offset 위치에 text를 삽입한다.
- replaceData(offset, count, text) - offset부터 (offset + count)까지의 텍스트를 text로 교체한다.
- splitText(offset) - offset 위치를 기준으로 텍스트 노드를 둘로 나눈다.
- substringData(offset, count) - offset 위치부터 (offset + count) 까지의 텍스트를 꺼낸다.

이들 메서드 외에도 length 프로퍼티도 지원되며 노드의 글자 개수를 반환한다. 이값은 nodeValue.length나 data.length와 같다.


텍스트 노드 생성
새 텍스트 노드를 생성할 때는 document.createTextNode() 메서드를 사용한다. 이 메서드는 매개변수로 삽입할 텍스트를 받는다. 새 텍스트 노드를 생성하면 ownerDocument 프로퍼티가 설정되지만 문서 트리에 삽입하기 전에는 브라우저 창에 표시되지 않는다. 텍스트 토드를 다른 텍스트 노드의 형제로 추가하면 두 텍스트 노드는 사이의 공백이 없는것으로 표시된다.


텍스트 노드 통일
형제 텍스트 노드를 하나로 합치는 메서드로 normalize()가 있고 Node 타입에 존재하므로 모든 노드에서 사용가능하다. 노드에서 normalize()를 호출하면 자식 노드를 텍스트 노드 하나로 병합하며 합쳐진 텍스트 노드의 nodeValue는 각 텍스트 노드의 nodeValue 프로퍼티를 하나로 합친 값과 같다.  브라우저가 문서를 파싱하면 형제 텍스트 노드는 생성되지 않고 DOM을 조작할 때만 생긴다.

※ 인터넷 익스플로러 6에서는 normalize() 메서드가 간혹 충돌한다. 확인할 수는 없었지만 이 문제는 패치를 통해 수정되었을수 있다.


텍스트 노드 분할
Text 타입에는 normalize() 의 반대 역할을 하는 splitText() 메서드가 있다. 이 메서드는 주어진 오프셋을 기준으로 텍스트 노드를 둘로 나눈다. 이 메서드가 반환하는 새 텍스트 노드의 parentNode는 원래 텍스트 노드의 parentNode와 같다. 텍스트 노드 분할은 텍스트 노드에서 데이터를 추출하는 DOM 파싱 테크닉에서 가장 자주 쓰인다.



10.1.5 Comment 타입
주석은 DOM에서 Comment 타입으로 표현된다.

- nodeType는 8이다.
- nodeName은 "#comment"이다.
- nodeValue는 주석 콘텐츠이다
- parentNode는 Document  또는 Element이다.
- 자식 노드는 가질 수 없다.

Commenet 타입은 Text 타입과 같은 원형을 상속하므로 Text 타입에 있는 문자열 메서드를 대부분 갖고 있는데 splitText()는 예외다. 또한 Text 타입과 마찬가지로 nodeValue나 data 프로퍼티로 주석의 콘텐츠를 가져올 수 있다.

※ Comment 타입 생성자와 프로토타입에 접근할 수 잇는 브라우저는 파이어폭스, 사파리, 크롬, 오페라다. 인터넷 익스플로러8은 태그 이름에 "!"가 들어가는 요소를 주석 노드로 간주한다. 즉 getElementsByTagName()이 주석 노드를 반환할 수 있다는 뜻이다. 인터넷 익스플로러 9에서는 커스텀 생성자 HTMLCommentElement가 주석을 나타낸다. 이 생성자에서 주석을 요소로 취급하는건 아니다.




10.1.6 CDATASection 타입
CDATA 섹션은 XML 기반 문서 전용이며 CDATASection 타입으로 표현된다. Comment와 마찬가지로 CDATASection 타입 역시 Text 타입과 같은 원형을 상속하므로 splitText()를 제외한 문자열 메서드를 모두 가진다. CDATASection 노드에는 다음 특징이 있다.

- nodeType은 4이다.
- nodeName은 "#cdata-section"이다.
- nodeValue는 CDATA 섹션의 콘텐츠이다.
- parentNode는 Document 또는 Element이다.
- 자식 노드는 가질 수 없다.

CDATA 섹션은 XML 문서에서만 유효하므로 대부분의 브라우저에서 CDATA 섹션을 부정확한 Comment 나 Element 로 잘못 파싱한다.

※ CDATASection  타입 생성자와 프로토타입에 접근할 수 잇는 브라우저는 파이어폭스와 사파리, 크롬, 오페라다. 인터넷 익스플로러는 버전 9까지 아직 이 타입을 지원하지 않는다.




10.1.7 DocumentType 타입
DocumentType 타입은 자주 쓰이지 않으며 이를 지원하는 웹 브라우저는 파이어폭스와 사파리, 오페라 뿐이다.

- nodeType은 10이다
- nodeName은 독타입 이름이다.
- nodeValue는 null이다.
- parentNode는 Document이다.
- 자식 노드는 가질 수 없다.




10.1.8 DocumentFragment 타입
DocumentFragment 타입은 마크업에 표현되지 않는 유일한 노드 타입이다. DOM에서는 문서 버퍼를 노드를 가지며 조작할 수 있을 뿐이고 그 외 복잡한 기능은 전부 제거된 "경량화된" 문서로 정의한다.

- nodeType은 11이다.
- nodeName은 "#document-fragment"이다.
- nodeValue는 null이다.
- parentNode는 null이다.
- 자식노드로 Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference를 가질수 있다.

문서 버퍼는 document.createDocumentFragment() 메서드로 생성하고 콘텐츠는 appendChild(), insetBefore()로 문서에 추가한다.



10.1.9 Attr 타입
요소의 속성은 DOM에서 Attr 타입으로 표현된다. Attr 타입 생성자와 프로토타입에 접근할 수 있는 브라우저는 인터넷 익스플로러 버전 8 이후 브라우저이고 기술적으로 속성은 요소의 attributes 프로퍼티 안에 존재하는 노드이다.

- nodeType은 11이다.
- nodeName은 속성이름이다.
- nodeValud는 속성 값이다.
- parentNode는 null이다.
- HTML에서는 자식노드를 가질 수 없다.
- XML에서는 자식 노드로 Text, EntityReference를 가질 수 있다.

Attribute 노드를 직접 참조하는 경우는 드물며 개발자들은 보통 getAttribute(), setAttribute(), removeAttribute()를 더 선호한다.
Attr 객체에는 세 가지 프로퍼티가 있는데 name은 속성 이름이며 nodeName과 같다. value는 속성 값이고 nodeValue와 같다. specified는 해당 속성이 코드에 명시되었는지 기본 값인지 나타내는 불리언이다.
새 attribute 노드를 생성할 때는  document.createAttribute()에 속성 이름을 넘겨 호출한다.

 


10.2 DOM 다루기

10.2.1 동적 스크립트
동적 스크립트에는 외부 파일을 불러오거나 텍스트를 직접 삽입하는 두 가지 방법이 있다. 동적으로 외부 파일을 불러오는 과정은 <scrtipt> 요소를 사용하는 것이고 직접 삽입하는 방법은 인라인 스크립트이다.


10.2.2 동적 스타일
css 스타일을 HTML 페이지에 삽입하는 요소는 두 가지이다. <link> 요소는 외부 CSS 파일을 불러올 때 사용하고 <style> 요소는 인라인 스타일에 사용한다. DOM 코드로 생성하는 link 요소가 제대로 동작하려면 body가 아니라 <head> 요소에 추가해야 한다.
스타일을 정의하는 다른 방법은 <style> 요소로 인라인 CSS 를 사용하는 것이 있는데 인터넷 익스플로러는 <style> 노드를 특별 취급하여 자식 노드에 대한 접근을 허용하지 않기 때문에 styleSheet를 써야한다. 이 프로퍼티에는 cssText라는 프로퍼티가 존재하며 이를 통해 css 코드를 설정할 수 있다.


10.2.3 테이블 조작
<table> 요소는 DOM 코어 메서드로 생성하기 어렵기 때문에 공식화할 수 있게끔 몇가지 프로퍼티와 메서드를 추가했다.

<table> 요소에 추가된 내용

- caption - <caption> 요소를 가리키는 포인터이다.
- tBodies - <tbody> 요소의 HTMLCollection이다.
- tBoot - <tfoot> 요소를 가리키는 포인터이다.
- tHead - <thead> 요소를 가리키는 포인터이다.
- rows - 테이블의 모든 행에 대한 HTMLCollection 이다.
- createThead() - <thead> 요소를 생성해 테이블에 삽입하고 그 참조를 반환한다.
- createTFoot() - <tfoot> 요소를 생성해 테이블에 삽입하고 그 참조를 반환한다.
- createCaption() - <caption> 요소를 생성해 테이블에 삽입하고 그 참조를 반환한다.
- deleteTHead() - <thead> 요소를 삭제한다.
- deleteTFoot() - <tfoot> 요소를 삭제한다.
- deleteCaption() - <caption> 요소를 삭제한다.
- deleteRow() - 주어진 위치의 행을 삭제한다.
- insertRow(pos) - rows 컬렉션에서 주어진 위치에 행을 삽입한다.


<tbody> 요소에 추가된 내용

- rows - <tbody> 요소에 포함된 행의 HTMLCollection이다.
- deleteRow(pos) - 주어진 위치의 행을 삭제한다.
- insertRow(pos) - rows 컬렉션에서 주어진 위치에 행을 삽입하고 그에 대한 참조를 반환한다.


<tr> 요소에 추가된 내용

- cells - <tr> 요소에 포함된 셀의 HTMLCollection이다.
- deleteCell(pos) - 주어진 위치의 셀을 삭제한다.
- insertCell(pos) - cells 컬렉션의 주어진 위치에 셀을 삽입하고 새 셀에 대한 참조를 반환한다.




10.2.4 노드리스트 사용
NodeList 객체와 이와 관련된 NamedNodeMap, HTMLCollection을 이해하면 DOM을 전체적으로 이해하는데 큰 도움이 된다. 문서 구조가 바뀔 때마다 컬렉션도 업데이트되므로 항상 정확한 정보를 반환한다는 뜻으로 NodeList 객체는 해당 객체에 접근할 때마다 수행되는 쿼리라고 말할수 있다.

 

 

 


 

'나홀로스터디 > JS For Web Dev' 카테고리의 다른 글

이벤트  (0) 2015.01.07
DOM 확장  (0) 2014.12.18
클라이언트 감지  (0) 2014.11.20
브라우저 객체모델  (0) 2014.11.12
함수 표현식  (0) 2014.10.23
Copyright © HuckleberryM All Rights Reserved | JB All In One Designed by CMSFactory.NET