1.1 The Document Object Model (a.k.a the DOM) Is a Hierarcy/Tree of Javascript Node Objects
1.2 Node Object Types
1.3 Subnode Objects Inherit From the Node Object
- Object < Node < Element < HTMLElement < (e.g., HTML*Element)
- Object < Node < Attr (this is desperated in DOM4)
- Object < Node < CharacterData < Text
Object < Node < Document < HTMLDocument
Object < Node < DocumentFragment
<a href="#">Hi</a>
<script>
var nodeAnchor = document.querySelector('a');
var props = [];
for (var key in nodeAnchor) {
props.push(key)l
}
// 알파벳 순으로 속성(properties)와 메서드(methods)가 로그에 출력됨
console.log(props.sort());
</script>
1.4 Properties and methods for working with nodes
모든 노드들은 속성과 메서드를 상속받아 DOM을 활용할 수 있도록 함 (DOM 순회, 검사, 추가, 조작...)
1.5 Identifying the Type and Name of a Node
모든 노드에는 Node에서 상속된 nodeType과 nodeName 속성이 존재
<a href="#">Hi</a>
<script>
// Node.DOCUMENT_TYPE_NODE
console.log(document.doctype.nodeName); // html
console.log(document.doctype.nodeType); // 10
// Node.DOCUMENT_NODE
console.log(document.nodeName); // #document
console.log(document.nodeType); // 9
// Node.DOCUMENT_FRAGMENT_NODE
createDocumentFragment()
console.log(document.createDocumentFragment().nodeName); // #document-fragment
console.log(document.createDocumentFragment().nodeType); // 11
// Node.ELEMENT_NODE
console.log(document.querySelector('a').nodeName) // A
console.log(document.querySelector('a').nodeType) // 1
// Node.TEXT_NODE
console.log(document.querySelector('a').firstChild.nodeName) // #text
console.log(document.querySelector('a').firstChild.nodeType) // 3
</script>
1.6 Getting a Node's Value
<a href="#">Hi</a>
<script>
console.log(document.querySelector('a').firstChild.nodeValue) // Hi
</script>
1.7 Using Javascript Methods to Create Element and Text Nodes
<!DOCTYPE html>
<html lang="en">
<body>
<script>
var elementNode = document.createElement('div');
var textNode = document.createTextNode('Hi');
</script>
</body>
</html>
1.8 Using Javascript Strings to Create and Add Element and Text Nodes to the DOM
<!DOCTYPE html>
<html lang="en">
<body>
<div id="A"></div>
<div id="B"></div>
<div id="C"></div>
<div id="D"></div>
<div id="E"></div>
<script>
document.getElementById('A').innerHTML = '<string>Hi</string>';
document.getElementById('B').outerHTML = '<div id="B" class="new">What is Shaking</div>';
document.getElementById('C').textContent = 'dude';
document.getElementById('D').innerText = 'Keep it';
document.getElementById('E').outerText = 'real!';
console.log(document.body.innerHTML);
/**
* <div id="A"><strong>Hi</string></div>
* <div id="B" class="new">What is Shaking</div>
* <div id="C">dude</div>
* <div id="D">Keep it</div>
* real!
*/
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<i id="elm">how</i>
<script>
var elm = document.getElementById('elm');
elm.insertAdjacentHTML('beforebegin', '<span>Hey-</span>');
elm.insertAdjacentHTML('afterbegin', '<span>dude-</span>');
elm.insertAdjacentHTML('beforeend', '<span>are</span>');
elm.insertAdjacentHTML('afterend', '<span>you?</span>');
console.log(document.body.innerHTML);
/**
* <span>Hey-</span>
* <i id="A"><span>dude-</span>how<span>are</span></i>
* <span>you?</span>
*/
</script>
</body>
</html>
1.9 Extracting Parts of the DOM Tree as Javascript Strings
<!DOCTYPE html>
<html lang="en">
<body>
<div id="A"><i>Hi</i></div>
<div id="B">Dude<strong> !</strong></div>
<script>
console.log(document.getElementById('A').innerHTML); // '<i>Hi</i>'
console.log(document.getElementById('B').textContent) // 'Dude !'
console.log(document.getElementById('B').innerText) // 'Dude !'
console.log(document.getElementById('B').outerText) // 'Dude !'
</script>
</body>
</html>
1.10 Using appendChild() and insertBefore() to Add Node Objects to the DOM
<!DOCTYPE html>
<html lang="en">
<body>
<p>Hi</p>
<script>
var elementNode = document.createElement('strong');
var textNode = document.createTextNode(' Dude');
document.querySelector('p').appendChild(elementNode);
document.querySelector('strong').appendChild(textNode);
console.log(document.body.innerHTML);
// <p>Hi<strong> Dude</strong></p>
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<ul>
<li>2</li>
<li>3</li>
</ul>
<script>
var text1 = document.createTextNode('1');
var li = document.createElement('li');
li.appendChild(text1);
var ul = document.querySelector('ul');
ul.insertBefore(li, ul.firstChild);
console.log(document.body.innerHTML);
/**
* <ul>
* <li>1</li>
* <li>2</li>
* <li>3</li>
* </ul>
*/
</script>
</body>
</html>
1.11 Using removeChild() and replaceChild() to Remove and Replace Nodes
<!DOCTYPE html>
<html lang="en">
<body>
<div id="A">Hi</div>
<div id="B">Dude</div>
<script>
// remove element node
var divA = document.getElementById('A');
divA.parentNod.removeChild(divA);
// remove text node
var divB = document.getElementById('B').firstChild;
divB.parentNod.removeChild(divB);
console.log(document.body.innerHTML);
// <div id="B"></div>
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="A">Hi</div>
<div id="B">Dude</div>
<script>
// replace element node
var divA = document.getElementById('A');
var newSpan = document.createElement('span');
newSpan.textContent = 'Howdy';
divA.parentNod.replaceChild(newSpan, divA);
// replace text node
var divB = document.getElementById('B').firstChild;
var newText = document.createTextNode('buddy');
divB.parentNod.replaceChild(newText, divB);
console.log(document.body.innerHTML);
</script>
</body>
</html>
1.12 Using cloneNode() to Clone Nodes
<!DOCTYPE html>
<html lang="en">
<body>
<ul>
<li>Hi</li>
<li>there</li>
</ul>
<script>
// cloneNode()에 파라미터 없을 경우 UL만 복제
var cloneOnlyUL = document.querySelector('ul').cloneNode();
// cloneNode()에 파라미터로 true를 보내면 자식 노드까지 복제
var cloneAllUL = document.querySelector('ul').cloneNode(true);
console.log(cloneOnlyUL.constructor); // logs HTMLUListElement()
console.log(cloneOnlyUL.innerHTML); // logs (an empty string) as only the ul was ccloned
console.log(cloneAllUL.constructor); // logs HTMLUListElement()
console.log(cloneAllUL.innerHTML); // logs <li>Hi</li><li>there</li>
</script>
</body>
</html>
1.13 Grokking Node Collections (i.e., NodeList and HTMLCollection)
1.14 Getting a List/Collection of All Immediate Child Nodes
<!DOCTYPE html>
<html lang="en">
<body>
<ul>
<li>Hi</li>
<li>there</li>
</ul>
<script>
var ulElementChildNodes = document.querySelector('ul').childNodes;
console.log('1', ulElementChildNodes);
// [0: text, 1: li, 2: text, 3: li, 4: text]
Array.prototype.forEach.call(ulElementChildNodes, function(item) {
console.log('2', item);
})
</script>
</body>
</html>
1.15 Converting a NodeList or HTMLCollection to a Javascript Array
<!DOCTYPE html>
<html lang="en">
<body>
<a href="#"></a>
<script>
console.log(Array.isArray(document.links));
// returns false, it's an HTMLCollection not an Array
console.log(Array.isArray(document.querySelectorAll('a')));
// return false, it's a NodeList not an Array
</script>
</body>
</html>
cf) NodeList과 HTML Collection을 실제 Javascript 배열로 변환하면 여러 가지 이점이 있음
<!DOCTYPE html>
<html lang="en">
<body>
<a href="#"></a>
<script>
console.log(Array.isArray(Array.prototype.slice.call(document.links)));
// returns true
console.log(Array.isArray(Array.prototype.slice.call(document.querySelectorAll('a'))));
// return false
</script>
</body>
</html>
1.16 Traversing Nodes in the DOM
<!DOCTYPE html>
<html lang="en">
<body>
<ul>
<!-- comment -->
<li id="A">Hi</li>
<li id="B">there</li>
<!-- comment -->
</ul>
<script>
// cache selection of the ul
var ul = document.querySelector('ul');
// what is the parentNode of the ul?
console.log(ul.parentNode.nodeName); // logs body
// what is the first child of the ul?
console.log(ul.firstChild.nodeName); // logs comment
// what is the last child of the ul?
console.log(ul.lastChild.nodeName); // logs text not comment, because there is a line break
// what is the nextSibling child of the li?
console.log(ul.querySelector('#A').nextSibling.nodeName); // logs text
// what is the previousSibling of the last li?
console.log(ul.querySelector('#B').previousSibling.nodeName); // logs text
// what is the first child of the ul?
console.log(ul.firstElementChild.nodeName); // logs li
// what is the last child of the ul?
console.log(ul.lastElementChild.nodeName); // logs li
// what is the nextSibling child of the li?
console.log(ul.querySelector('#A').nextElementSibling.nodeName); // logs li
// what is the previousSibling of the last li?
console.log(ul.querySelector('#B').previousElementSibling.nodeName); // logs li
// what are the element only child nodes of the ul?
console.log(ul.children); // HTMLCollection, all child nodes including text nodes
// what is the parent element of the li?
console.log(ul.firstElementChild.nodeName); // logs ul
</script>
</body>
</html>
1.17 Verifying a Node Position in the DoM Tree with Contains() and compareDocumentPosition()
<!DOCTYPE html>
<html lang="en">
<body>
<script>
var inside = document.querySelector('html').contains(document.querySelector('body'));
console.log(inside); // logs true
</script>
</body>
</html>
0 - Elements are identical. (동일)
1 - DOCUMENT_POSITION_DISCONNECTED
// Set when selected node ans passed-in node are not in the same doucment (존재하지 않음)
2 - DOCUMNET_POSITION_PRECEDING
// Set when passed-in node is following selected nnode. (선택된 거 앞에)
4 - DOCUEMNT_POSITION_FOLLOWING
// Set when passed-in node is following selected node. (선택된 거 뒤에)
8 - DOCUEMNT_POSITION_CONTAINS
// Set when passed-in node is an anscestor of selected node. (선택된 거 조상)
16, 10 - DOCUEMNT_POSITION_CONTAINED_BY (16, 10 in headecimal)
// Set when passed-in node is descendant of selected node. (선택된 거 자손)
1.18 Determining Whether Two Nodes Are Identical
<!DOCTYPE html>
<html lang="en">
<body>
<input type="text" />
<input type="text" />
<textarea>foo</textarea>
<textarea>bar</textarea>
<script>
// logs true, because they are exactly identical
var input = document.queryselectorAll('input');
console.log(input[0].isEqualNode(input[1]));
// logs false, beacuase the child text node is not the same
var textarea = document.querySelectorAll('textarea');
console.log(textarea[0].isEqulNode(textarea[1]));
</script>
</body>
</html>
cf) 두 노드가 정확히 같은지가 아닌 두 노드가 같은 reference를 참조하고 있는지 알고 싶다면 === 연산자를 통해서 확인할 수 있음