DOM(Document Object Model) 은 HTML, XML 구조화된 문서를 객체 지향적으로 표현한 프로그래밍 interface 이다. DOM은 동적으로 문서의 내용, 구조, 스타일에 접근하고 변경하는 수단으로 W3C 에서 표준화한 여러 개의 API의 기반이 된다. DOM 은 구조화된 nodes와 property 와 method 를 갖고 있는 objects로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.
모든 HTML elements는 객체로 정의하며 인터페이스는 객체에 대한 프로퍼티와 메서드로 구성된다. Property 는 element value 이고 Method 는 element 조작을 하는 행위이다.
두 가지 예를 보면 아래와 같다.
최근의 유행하는 React, Angular, Vue 는 DOM API 기반으로 문서 조작을 위한 편리한 기능을 제공하는 프레임워크이다.
querySelector() 메서드 이용시 파라미터로 CSS 선택자를 넣어줘야 한다. 선택자의 구분은 아래와 같이 구분한다. querySelector()는 HTMLCollection 아닌 첫 번째 element 를 반환한다.
사용자가 이용하는 브라우저 버전은 모두 다르며, 각 브라우저 마다 다른 기능을 가지고 있어 파편화가 발생한다. polyfill은 구형 브라우저에서 지원하지 않는 기능(ex, HTML5 API)을 지원하여 최신 브라우저와 같은 동작을 하게끔 하위 호환성을 맞춰준다.
<body>
<h1>selector test</h1>
<section>
<h2> red section </h2>
<ul>
<li class="red">apple</li>
<li class="red">orange</li>
<li>banana</li>
<li>grape</li>
<li>strawberry</li>
</ul>
</section>
<Br>
<section>
<h2> blue section </h2>
<ul>
<li class="green blue">apple</li>
<li class="red">orange</li>
<li>banana</li>
<li>grape</li>
<li>strawberry</li>
</ul>
</section>
</body>
var sb = document.querySelector("ul");
var potato = document.createElement("li");
potato.innerText = 'potato';
sb.appendChild(potato);
var banana = document.querySelector('li:nth-child(3)');
var potato = document.createElement('li');
potato.innerText = 'potato';
document.querySelector('ul').insertBefore(potato, banana);
var banana = document.querySelector('li:nth-child(3)');
banana.insertAdjacentHTML('beforebegin', '<li> potato </li>');
var apple = document.querySelector('li');
var banana = document.querySelector('li:nth-child(4)');
banana.insertAdjacentElement('afterend', apple);
var ul = document.querySelector('ul');
var reds = document.querySelectorAll('li.red');
for (i = 0, len = reds.length; i < len; ++i) {
ul.removeChild(reds[i]);
}
// 재귀 이용...
function rec(element) {
let children = element.children;
if(children.length < 1) { return element.classList.contains('blue'); }
for(let item of children) {
if(item.className == 'blue') { return true; }
if(children.length >= 1 && rec(item)) { return true; }
}
return false;
}
var section = document.getElementsByTagName('section');
for(let sec of section) {
if(rec(sec)) {
sec.removeChild(sec.querySelector('h2'));
}
}
// CSS 선택자 이용 ==> 권장 방법
let blueNode = document.querySelectorAll('section .blue');
for(let item of blueNode) {
let section = item.closest('section');
let h2 = section.querySelector('h2');
section.removeChild(h2);
}