Documnet Object Model
인 DOM은
HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API
즉,프로퍼티
와메서드
를 제공하는트리 자료구조
이다
DOM API를 통해 HTML의 구조나 내용 또는 스타일을 동적으로 제어
트리자료 구조이며 계층구조
로 이루어짐
부모
노드와 자식
노드로 구성
노드 객체들로 구성된 트리자료 구조
Document Object Model
root node, leaf node 가 존재
DOM은 HTML
문서의 계층적 구조, 정보를 표현하며, 노드 객체의 종류.
즉, 노드 종류에 따라 필요한 기능을 프로퍼티
와 메서드
집합인 DOM API로 제공한다
DOM API로 HTML
문서의 구조나 내용, 스타일을 동적
으로 제어 할 수 있다
HTML 요소
HTML을 구성하는 개별적인 요소
트리자료구조
부모노드
와자식노드
로 구성
하나의 최상위 노드에서 시작하며, 최상위 노드는루트노드
이고 자식노드가 없는노드는리프노드
document node
최상위에 존재하는 루트 노드로써 document 객체
를 말함
요소,어트리뷰트,텍스트 노드에 접근하려면 반드시 문서노드
를 거쳐야 함
element node
문서의 구조
attribute node
요소노드
에만 연결되어 있으므로, 어트리뷰트에 접근하기 위해서는 먼저 요소노드
에 접근해야
text node
요소노드의 자식노드
DOM을 구성하는 노드 객체는 ECMAScript사양에 정의된
표준 빌트인 객체
가 아니라
브라우저 환경에서 추가적으로 제공하는호스트 객체
이다
하지만, 노드 객체도자바스크립트 객체
이므로 프로토타입에 의한 상속구조를 갖는다.
Object
객체
EventTarget
이벤트를 발생시키는 객체
Node
트리 자료구조의 노드 객체
Element
브라우저가 렌더링할 수 있는 웹 문서의 요소 (HTML, XML, SVG)를 표현하는 객체
HTMLElement
웹 문서의 요소 중에서 HTML 요소를 표현하는 객체
유일한 값
이어야 하므로 여러 개중 첫 번째 요소
노드만 반환한다 HTMLCollection
반환 (유사배열 객체 + 이터러블)Document.prototype.getElementByTagName
HTMLCollection
객체를 반환Document.prototype.getElementByClassName
중복
이 가능한 값NodeList
//querySelectorAll은 DOM객체인 NodeList를 반환
const $elems = document.querySelectorAll('.red');
$elems.forEach(elem => elem.className = 'blue');
HTML Collection
여러개의 요소노드 객체를 갖는 DOM 컬렉션 객체
노드 객체의 상태 변화를 실시간으로 반영하는살아있는
DOM 컬렉션 객체
for문
으로 순회 가능하다//유사배열 객체 이면서 이터러블인 HTMLCollection을 배열로 변환하여 순회 [...$elems].forEach(elem => elem.className ='blue');
NodeList
노드 객체의 상태변경을 실시간으로 반영하지
못하는
객체
childNodes 프로퍼티가반환하는 NodeList 객체는 HTMLCollection 객체와 같이실시간
으로 상태 변경을 반영하는 live객체로 동작함을 주의!
따라서 노드 객체의 상태 변경과 상관없이
DOM컬렉션을 사용하려면 HTML Collection
이나 NodeList
객체를 배열로 변환하여 사용하는 것을 추천!
* { 전체 선택 }
p {태그가 p }
#foo { id 선택자 foo 모두 선택 }
.foo { class선택자 foo 모두 선택 }
input [type=text] { input 요소 중에 type 어트리뷰트 값이 text인 요소 모두 선택 }
div p { div요소의 후손 요소 중 p요소 모두 선택 }
div > p { div요소의 자식 요소 중 p요소 모두 선택 }
p + ul { p의 형제 요소 중에 p 바로 뒤에 위치하는 ul요소 모두 선택 }
p ~ ul { p의 형제 요소 중에 p 뒤에 위치하는 ul 요소 모두 선택 }
a : hover { hover 상태인 a 요소 모두 선택 }
p :: before { p요소 앞에 위치하는 공간을 선택 }
//class attribute값이 banana인 첫번째 요소를 탐색하여 반환
const $elem = document.querySelector('.banana');
//취득한 요소 노드의 style.color 프로퍼티 값 변경
$elem.style.color = 'red'
id 어트리뷰트가 있으면 getElementById를 사용하고,
그 외의 경우에는querySelector
,querySelectorAll
메서드를 사용하는것을 권장
Node.prototype.childNodes
자식 노드 모두 탐색해 NodeList
에 담아 반환
Element.prototype.children
자식 노드 중에서 요소노드만 모두 탐색해 HTMLCollection
에 담아 반환
Node.prototype.firstChild
첫번째 자식 노드 / 텍스트
요소
노드
Node.prototype.lastChild
마지막 자식 노드 / 텍스트
요소
노드
Element.prototype.firstElementChild
첫번째 자식 노드 / 요소
노드
Element.prototype.lastElementChild
마지막 자식 노드 / 요소
노드
텍스트
노드도 포함없다
Node.prototype.previousSibling
부모 노드가 같은 형제 노드 중에서 자신의 이전 형제 노드 / 텍스트
요소
노드
Node.prototype.nextSibling
부모 노드가 같은 형제 노드 중에서 자신의 다음 형제 노드 / 텍스트
요소
노드
Element.prototype.previousElementSibling
부모 노드가 같은 형제 노드 중에서 자신의 이전 형제 노드 / 요소
노드
Element.prototype.nextElementSibling
부모 노드가 같은 형제 노드 중에서 자신의 다음 형제 노드 / 요소
노드
innerHTML
insertAdjacentHTML 메서드
beforebegin
afterbegin
beforend
afterend
createElement : 요소 생성 (아무런 자식 노드도 없음)
createTextNode(text) : 텍스트 노드 생성
appendChild (childNode)
마지막 자식으로 추가
insertBefore (newNode, childNode)
마지막 인자를 null
로 하면 마지막 자식노드로 추가됨
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li>Apple</li>
<li>Banana</li>
</ul>
</body>
<script>
const $fruits = document.getElementById('fruits');
// 요소 노드 생성
const $li = document.createElement('li');
// 텍스트 노드를 $li 요소 노드의 마지막 자식 노드로 추가
$li.appendChild(document.createTextNode('Orange'));
// 두 번째 인수로 전달받은 노드가 null이면 $li 요소 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
$fruits.insertBefore($li, null);
</script>
</html>
HTML 어트리뷰트의 역할은 HTML 요소의
초기 상태
를 지정 +변하지 않음
하지만, 요소 노드는 2개의상태
(초기, 최신)를 가지고 있음
따라서최신상태
를 관리할 DOM 프로퍼티가 필요
HTML 어트리뷰트
문자열
DOM 프로퍼티
문자열일 수도 아닐수도 있음
data
어트리뷰트 + dataset
프로퍼티
data- 접두사 다음에 붙인 이름을 카멜케이스
로 변환한 프로퍼티를 가짐
<!DOCTYPE html>
<html>
<body>
<ul class="users">
<li id="1" data-user-id="7621" data-role="admin">Lee</li>
<li id="2" data-user-id="9524" data-role="subscriber">Kim</li>
</ul>
<script>
const users = [...document.querySelector('.users').children];
// user-id가 '7621'인 요소 노드를 취득한다.
const user = users.find(user => user.dataset.userId === '7621');
// user-id가 '7621'인 요소 노드에서 data-role의 값을 취득한다.
console.log(user.dataset.role); // "admin"
// user-id가 '7621'인 요소 노드의 data-role 값을 변경한다.
user.dataset.role = 'subscriber';
// dataset 프로퍼티는 DOMStringMap 객체를 반환한다.
console.log(user.dataset); // DOMStringMap {userId: "7621", role: "subscriber"}
</script>
</body>
</html>