DOM: 문서 객체 모델
문서 객체 모델(DOM)은 HTML 문서 구조를 말합니다.
HTML 문서의 구조에서 최상위 객체로는 <html>이 있으며, 그 하위 객체로는 <head>와 <body>가 있습니다.
모든 HTML 태그는 객체 또는 노드라 합니다. Document는 document 노드라 하고 태그들도 모두 노드입니다. HTML 태그 내의 텍스트 역시 텍스트 노드라 하고 주석도 주석 노드라 합니다. 위 그림 처럼 노드들은 트리 구조를 구성기 때문에 <html> 태그를 루트 노드가 되고, <head>태그와 <body>태그는 루트 노드의 자식 노드가 됩니다.
이 같은 노드들은 모두 JS를 통해 접근할 수 있고 조작할 수 있습니다. 예를 들어 <body> 태그는 document.body로 접근할 수 있고 텍스트 노드는 innerHTML속성으로 접근할 수 있습니다.
DOM 노드 탐색하기
노드에 접근하기 위해서는 무조건 document 객체에서 시작합니다. 위 그림으로 바로 이해할 수 있듯이 document 노드는 DOM에 접근하기 위한 진입점이기 때문입니다.
트리 상단 노드 탐색
트리 상단의 , , 는 다음과 같이 접근할 수 있습니다.
- <html> - document.documentElement
- <head> - document.head
- <body> - document.body
노드 간 탐색
자식 노드: 바로 아래의 자식 노드 입니다.
후손 노드: 자식노드와 자식 노드의 모든 자식 노드들 입니다.
- parentNode - 부모 요소 노드
- childNodes[nodenumber] - 모든 자식 노드를 담고 있습니다.
- firstChild - 첫 번째 자식 요소 노드, childNodes[0]과 같습니다.
- lastChild - 마지막 자식 요소 노드, childNodes[element.childNodes.length - 1]과 같습니다.
- nextSibling - 다음 형제 노드
- previousSibling - 이전 형제 노드
childNodes은 Iterable한 컬렉션입니다. 때문에 다음과 같은 특징을 가집니다.
컬렉션이지 배열이 아님은 주의!!
아래 세 개는 같은 노드에 접근합니다.
HTML 요소
HTML 요소 찾기
document.getElementById() | id를 통해 요소 찾기 |
document.getElementsByTagName() | 태그 이름 통해 요소 찾기 |
document.getElementsByClassName() | 클래스 이름 통해 요소 찾기 |
document.querySelector() | 파라미터로 입력받는 CCS 선택자로 찾은 요소들 중 첫 번째 요소 반환 |
document.querySelectorAll() | 파라미터로 입력받은 요소들을 찾아 NodeList로 반환 |
HTML 요소 변경
element.innerHTML = content | inner HTML content 변경 |
element.attribute = value | HTML 요소의 value 변경 |
element.style.property = style | HTML 요소의 style 변경 |
요소 추가 및 삭제
document.createElement(element) | HTML 요소 생성 |
document.removeChild(element) | HTML 요소 삭제 child.parentNode.removeChild(child) 형식으로 노드를 삭제해주어야 합니다. |
document.appendChild(element) | HTML 요소 추가 |
document.replaceChild(new, old) | HTML 요소 old에서 new로 대체 |
document.write(text) | Write into the HTML output stream |
예시
- document.createElement()를 통해 HTML 요소를 생성(예. <h1>, <button> 등)
- element.innerHTML 또는 document.createTextNode()를 통해 텍스트 입력
- document.appendChild()를 통해 생성하고 텍스트를 작성한 HTML 요소를 추가
appendChild()로 새 요소를 추가하면 마지막 노드에 추가됩니다. 만약 노드의 위치를 바꿔 삽입하고 싶으면 다음 방법을 사용하면 됩니다.
id가 div1인 요소의 자식 노드 중 id가 p1인 자식 노드 전에 삽입하는 예제입니다.
노드 속성 접근
노드의 이름: nodeName
- 요소 노드인 경우: 태그 이름
- 속성 노드인 경우: 속성 이름
- 텍스트 노드인 경우: #text
- 문서 노드인 경우: #document
- 읽기 전용이기 때문에 수정이 불가능합니다.
노드의 값: nodeValue
- 요소 노드인 경우: null
- 텍스트 노드인 경우: 텍스트 값
- 속성 노드인 경우: 속성 값
노드 유형: nodeType
노드의 유형을 반환합니다. 읽기 전용입니다.
- 요소노드: 1
- 속성노드: 2
- 텍스트노드: 3
- 주석노드: 8
- 문서노드: 9
- 문서타입노드: 10 (ex:<!Doctype html>)
DOM Collections
getElementsByTagName()은 HTML Collection을 반환합니다.
DOM NodeList
- 문서에서 추출된 노드의 리스트입니다.
- HTMLCollection과 거의 유사합니다.
- childNodes과 querySelectorAll()는 NodeList를 반환합니다.
- 인덱스로 배열처럼 접근할 수도 있고, myNodeList.length를 통해 길이도 구할 수 있습니다. 하지만 이 역시 배열은 아님을 주의!!
HTMLCollection VS NodeList
공통점
HTMLCollections과 NodeList는 거의 같다고봐도 됩니다. 둘 다 문서에서 추출한 노드(요소) 컬렉션이고, 배열은 아니지만 배열처럼 인덱스 접근이 가능하고 length를 통해 길이를 구할 수 있습니다.
차이점
- HTMLCollection
- 동적이기 때문에 DOM에 새로운 요소가 추가되면 HTMLCollection은 바로 새로운 요소를 가져온다
- HTMLCollection 객체는 <div>, <p> 등과 같은 요소 노드만 포함합니다.
- 자식노드에 접근할 때 id, name, 인덱스를 통해 자식 노드에 접근합니다.
- 반복문을 돌때 유사 배열 객체이기 때문에 for..of 문을 사용하여 접근합니다.
- getElementByTagName(), getElementByClassName()
- NodeList
- 정적이기 때문에 DOM에 새로운 요소가 추가되면 요소를 가져오지 못합니다.
- NodeList 객체는 요소 노드, 속성 노드, 텍스트 노드 등을 포함합니다.
- 자식노드에 접근할 때 id, name으로 자식 노드에 접근할 수 없고 인덱스로만 접근 가능합니다.
namedItem() 메서드를 갖고 있지 않기 때문입니다. - 반복문을 돌때 forEach() 메서드를 사용하여 접근합니다.
- getElementByName(), querySelectorAll()
'Front-End > JS' 카테고리의 다른 글
JS Web API ( storage, fetch, geolocation ) (0) | 2023.04.28 |
---|---|
JS BOM( Browser Object Model ): 브라우저 객체 모델 (0) | 2023.04.28 |
JS async & await (0) | 2023.04.28 |
JS Promise를 사용한 비동기 처리 (0) | 2023.04.27 |
JS addEventListener 사용법 ( + capturing, bubbling ) (0) | 2023.04.27 |