- 모든 요소와 요소의 어트리뷰트, 텍스트를 각각의 객체로 만들고
이들 객체를 부자 관계로 표현할 수 있는 트리 구조로 구성한 것- DOM은 자바스크립트를 통해 동적으로 변경할 수 있으며
변경된 DOM은 렌더링에 반영됨
- DOM에 접근하고 변경하는 프로퍼티와 메소드의 집합
- 웹 문서의 동적 변경을 위해 DOM은 프로그래밍 언어가 자신에
접근하고 수정할 수 있는 방법을 제공하는데 일반적으로 프로퍼티와
메소드를 갖는 자바스크립트 객체로 제공됨- 정적인 웹페이지에 접근하여 동적으로 웹페이지를 변경하기 위한
유일한 방법은 메모리 상에 존재하는 DOM을 변경하는 것이고,
이때 필요한 것이 DOM API
- HTML 문서에 대한 모델 구성
브라우저는 HTML 문서를 로드한 후 해당 문서에 대한 모델을
메모리에 생성함. 이때 모델은 객체의 트리로 구성되는데 이것을
DOM tree라 함
- HTML 문서 내의 각 요소에 접근 / 수정
DOM은 모델 내의 각 객체에 접근하고 수정할 수 있는 프로퍼티와
메소드를 제공함. DOM이 수정되면 브라우저를 통해 사용자가
보게 될 내용 또한 변경됨
- 문서 노드(Document Node)
트리의 최상위에 존재하며 각각 요소, 어트리뷰트, 텍스트 노드에 접근하려면
문서 노드를 통해야 함. 즉, DOM tree에 접근하기 위한 시작점
- 요소 노드(Element Node)
HTML 요소를 표현
HTML 요소는 중첩에 의해 부자 관계를 가지며 이 부자 관계를 통해 정보를 구조화
어트리뷰트, 텍스트 노드에 접근하려면 먼저 요소 노드를 찾아 접근해야 함
모든 요소 노드는 요소별 특성을 표현하기 위해 HTMLElement 객체를 상속한 객체로 구성
- 어트리뷰트 노드(Attribute Node)
HTML 요소의 어트리뷰트를 표현
해당 어트리뷰트가 지정된 요소의 자식이 아니라 해당 요소의 일부로 표현
해당 요소 노드를 찾아 접근하면 어트리뷰트를 참조, 수정할 수 있음
- 텍스트 노드(Text Node)
HTML 요소의 텍스트를 표현
요소 노드의 자식이며 자신의 자식 노드를 가질 수 없음
DOM tree의 최종단
- document.getElementById(id)
id 어트리뷰트 값으로 요소 노드 한 개 선택
복수개가 선택된 경우, 첫번째 요소만 반환
- document.querySelector(cssSelector)
CSS 셀렉터를 사용하여 요소 노드 한 개 선택
복수개가 선택된 경우, 첫번째 요소만 반환
- document.getElementsByClassName(class)
class 어트리뷰트 값으로 요소 노드를 모두 선택
공백으로 구분하여 여러 개의 class 지정 가능
- parendNode
부모 노드를 탐색
- firstChild, lastChild
자식 노드를 탐색
- hasChildNodes()
자식 노드가 있는지 확인하고 Boolean 값을 반환
- childNodes
자식 노드의 컬렉션을 반환
텍스트 요소를 포함한 모든 자식 요소를 반환
- children
자식 노드의 컬렉션을 반환
자식 요소 중에서 Element type 요소만을 반환
- previousSibling, nextSibling
형제 노드를 탐색
text node를 포함한 모든 형제 노드 탐색
- previousElementSibling, nextElementSibling
형제 노드를 탐색
형제 노드 중에서 Element type 요소만을 탐색
텍스트 노드에 접근하는 방법
1. 해당 텍스트 노드의 부모 노드를 선택. 텍스트 노드는 요소 노드의 자식이다.
2. firstChild 프로퍼티를 사용하여 텍스트 노드를 탐색
3. 텍스트 노드의 유일한 프로퍼티(nodeValue)를 이용하여 텍스트를 취득
4. nodeValue를 이용하여 텍스트를 수정
- nodeValue
노드의 값을 반환
- className
class 어트리뷰트의 값을 취득 또는 변경
className 프로퍼티에 값을 할당하는 경우,
class 어트리뷰트가 존재하지 않으면 class 어트리뷰트를 생성하고 지정된 값을 설정.
class 어트리뷰트의 값이 여러 개일 경우,
공백으로 구분된 문자열이 반환되므로 String 메소드 split(' ')를 사용하여 배열로 변경하여 사용
- classList
add, remove, item, toggle, contains, replace 메소드를 제공
- id
id 어트리뷰트의 값을 취득 또는 변경
id 프로퍼티에 값을 할당하는 경우, id 어트리뷰트가 존재하지 않으면
id 어트리뷰트를 생성하고 지정된 값을 설정
- hasAttribute(attribute)
지정한 어트리뷰트를 가지고 있는지 검사
- getAttribute(attribute)
어트리뷰트의 값을 취득
- setAttribute(attribute, value)
어트리뷰트와 어트리뷰트 값을 설정
- removeAttribute(attribute)
지정한 어트리뷰트 제거
마크업이 포함된 콘텐츠를 추가하는 행위는 크로스 스크립팅 공격에 취약하므로 주의가 필요
- textContent
요소의 텍스트 콘텐츠를 취득 또는 변경 (마크업 무시)
textContent를 통해 요소에 새로운 텍스트를 할당하면 텍스트를 변경할 수 있음
이때 순수한 텍스트만 지정해야 하며 마크업을 포함시키면 문자열로 인식되어 그대로 출력됨
- innterText
요소의 텍스트 콘텐츠에만 접근할 수 있음
비표준 / CSS에 순종적 / CSS를 고려해야 하므로 textContent 프로퍼티보다 느리다
- innerHTML
해당 요소의 모든 자식 요소를 포함하는 모든 콘텐츠를 하나의 문자열로 취득 (마크업 포함)
마크업이 포함된 콘텐츠를 추가하는 것은 크로스 스크립팅 공격에 취약함
innerHTML 프로퍼티를 사용하지 않고 새로운 콘텐츠를
추가하려면 DOM을 직접 조작해야 함
1. 요소 노드 생성
createElement() 메소드를 사용하여 새로운 요소 노드를 생성
createElement() 메소드의 인자로 태그 이름을 전달
2. 텍스트 노드 생성
createTextNode() 메소드를 사용하여 새로운 텍스트 노드를 생성
경우에 따라 생략될 수 있지만 생략하는 경우, 콘텐츠가 비어 있는 요소가 됨
3. 생성된 요소를 DOM에 추가 appendChild() 메소드를 사용하여
생성된 노드를 DOM tree에 추가 또는 removeChild() 메소드를 사용하여
DOM tree에서 노드를 삭제
- createElement(tagName)
태그 이름을 인자로 전달하여 요소 생성
- createTextNode(text)
텍스트를 인자로 전달하여 텍스트 노드 생성
- appendChild(Node)
인자로 전달한 노드를 마지막 자식 요소로 DOM 트리에 추가
- removeChild(Node)
인자로 전달한 노드를 DOM 트리에서 제거
innerHTML
- DOM 조작 방식에 비해 빠르고 간편
- 간편하게 문자열로 정의한 여러 요소를 DOM에 추가할 수 있음
- 콘텐츠를 취득할 수 있음
단점- XSS 공격에 취약점이 있기 때문에 사용자로부터 입력받은 콘텐츠
(댓글, 사용자 이름 등)를 추가할 때 주의하여야 함- 해당 요소의 내용을 덮어 씀. 즉, HTML을 다시 파싱. 비효율적
DOM 조작 방식
- 특정 노드 한 개(노드, 텍스트, 데이터 등)를 추가할 때 적합
단점- innerHTML보다 느리고 더 많은 코드가 필요
innerHTML은 크로스 스크립팅 공격(XSS)에 취약함
untrusted data의 경우, 주의하여야 함
텍스트를 추가 또는 변경 시에는 textContent,
새로운 요소의 추가 또는 삭제 시에는 DOM 조작 방식을 사용해야 함