![thumbnail](/static/011ac8fef6251889a8b621b0f3712ce4/b1abc/221009_dom-thumbnail.png)
DOM
문서 객체 모델(Document Object Model, DOM)은 HTML, XML 문서용 API로 HTML 문서를 읽어 웹 화면에 띄워 주는 역할을 한다. 또한, 자바스크립트와 같은 프로그래밍 언어가 DOM 구조에 접근해 문서 구조, 스타일, 내용 등을 변경할 수 있게 한다.
HTML과 Javascript는 언어가 달라 서로를 이해하지 못한다. 정적인 HTML 문서의 요소들을 자바스크립트가 동적으로 만들어주기 위해서는 자바스크립트가 HTML의 언어를 이해할 수 있도록 해야 하는데, 그 역할을 하는 것이 바로 DOM이다.
Node(노드)
HTML 요소는 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체로 변환된다. HTML 문서는 HTML 요소들의 집합으로 이뤄지는데, 요소 간에는 중첩 관계에 의한 부모 자식 관계가 형성된다.
DOM은 이 관계를 반영하여 노드 객체들을 계층적인 트리 구조로 나타낸다.
트리의 최상위 노드를 root라 하고 일반적으로 HTML 문서에서 <html>
이 root 노드가 된다. root 노드는 0개 이상의 자식 노드를 가지며, 자식 노드가 없는 노드를 리프(leaf) 노드라고 한다.
요소 노드에 접근하기
document.getElementById()
document.getElementById(id);
document.getElementById()
메서드는 인수로 전달한 id 값과 일치하는 요소를 찾고 해당하는 Element 객체를 반환한다. 일치하는 요소가 존재하지 않을 경우 null을 반환한다. id는 HTML 문서 내의 유일한 값이기 때문에 특정 요소를 빠르게 찾을 수 있다.
document.querySelector()
document.querySelector(selectors);
document.querySelector()
는 지정한 선택자(selector)와 일치하는 첫 번째 요소를 반환한다. 일치하는 요소가 없을 경우 null을 반환한다.
선택자(selector)
- id는 ’#‘를 붙인다.
- class는 ’.’을 붙인다.
- 요소는 요소 이름 그대로
=> 선택자는 CSS 선택자와 동일하다.
document.querySelectorAll()
HTML 문서의 선택자와 일치하는 모든 요소에 접근하고 싶다면 document.querySelectorAll()
을 사용하면 된다.
document.querySelectorAll(selectors);
선택자와 일치하는 모든 요소를 NodeList
객체로 반환한다. NodeList는 유사 배열 객체로 DOM 변경이 있어도 바뀌지 않는다.
노드 추가하기
document.createElement()
document.createElement(tagName);
document.createElement()
는 tagName으로 지정된 HTML 요소 노드를 생성한다.
const newDiv = document.createElement("div"); // div 요소 생성
appendChild(), insertBefore()
appendChild(aChild);
insertBefore(newNode, referenceNode);
appendChild()
는 부모 노드의 끝에 자식 노드를 추가하는 메서드이고 insertBefore()
는 부모의 특정 노드 앞에 노드를 삽입하는 메서드이다.
prepend(), append(), before(), after()
appendChild()
, insertBefore()
이외에도 새로운 노드를 추가하거나 노드를 이동할 수 있는 메서드가 있다.
prepend()
: 요소 내부의 처음으로 이동append()
: 요소 내부의 마지막으로 이동before()
: 요소 앞으로 이동after()
: 요소 뒤로 이동
prepend()와 append()는 문자열을 인자로 받을 경우 자동으로 텍스트 노드를 생성하여 삽입한다.
📌 appendChild() VS append()
append()
는 문자열을 인자로 넘겨줄 수 있지만appendChild()
는 문자열을 인자로 넘길 수 없다.append()
의 경우, 여러 노드를 한 번에 추가할 수 있으나appendChild()
는 여러 노드를 추가하려면 메서드를 여러 번 호출해야 한다.이러한 특성으로 인해 append()의 사용을 더 권장한다. 그러나 append()는 IE 브라우저에서 지원되지 않기 때문에 주의해야 한다.
노드 제거하기
removeChild(), remove()
parentNode.removeChild(child);
remove();
removeChild()
와 remove()
모두 노드를 제거할 때 사용한다. removeChild()
는 부모 노드에서 메서드를 호출하여 제거하고자 하는 노드를 인자로 넘기는 반면, remove()
는 제거하고 싶은 노드에서 직접 메서드를 호출하면 된다. remove()가 removeChild()보다 더 간결하게 작성할 수 있지만, 이 역시 IE에서 지원하지 않으므로 주의해야 한다.
노드 특정 위치에 삽입하기
insertAdjacentHTML()
element.insertAdjacentHTML(position, text);
insertAdjacentHTML()
은 HTML, XML로 해석 가능한 문자열을 파싱한 뒤 노드를 생성해 특정 위치에 삽입하는 메서드이다.
position은 아래 4가지만 가능하다.
- beforebegin: 요소 바로 앞
- afterbegin: 요소 내부 가장 첫 번째 자식 요소
- beforeend: 요소 내부 마지막 자식 요소
- afterend: 요소 바로 뒤
innerHTML
과 얼핏 비슷하지만 다른 점이 분명히 존재한다. innerHTML
의 경우 이미 사용 중인 요소를 모두 없애고 다시 파싱을 하는 반면, innerAdjacentHTML()
은 사용 중인 요소는 파싱하지 않고 새로 추가되는 노드만 작업한다. 때문에 innerAdjacentHTML()이 성능적으로 innerHTML보다 이점이 있다.
References