DOM
(document object model)
Creating elements
Creating html elements
var div = document.createElement('div');
div instanceof HTMLDivElement; // true
div.nodeName // 'DIV'
div.nodeType === Node.ELEMENT_NODE; // trueCreating a `div` html element
var ul = document.createElement('ul');
ul instanceof HTMLUListElement; //true
ul.nodeName; // 'UL'
ul.nodeType === Node.ELEMENT_NODE; // trueCreating a `ul` html element
Node types

Creating character data elements
var comment = document.createComment('Empty node');
comment.nodeName; // #comment
comment instanceof CharacterData; // true;
comment.nodeType === Node.COMMENT_NODE; // true;Creating `comment` character data element
var text = document.createTextNode('Warning');
text.nodeName; // #text
text instanceof CharacterData; // true;
text.nodeType === Node.TEXT_NODE; // true;Creating `text` character data element
Adding elements
Node.appendChild method
// creating elements
var ulElement = document.createElement('ul');
var liElement1 = document.createElement('li');
var liElement2 = document.createElement('li');
var lineBreak1 = document.createTextNode('\n');
var lineBreak2 = lineBreak1.cloneNode(lineBreak1);
var lineBreak3 = lineBreak1.cloneNode(lineBreak1);
var text = document.createTextNode('Warning');
var comment = document.createComment('Empty node');
// appending elements
liElement1.appendChild(text);
liElement2.appendChild(comment);
ulElement.appendChild(lineBreak1);
ulElement.appendChild(liElement1);
ulElement.appendChild(lineBreak2);
ulElement.appendChild(liElement2);
ulElement.appendChild(lineBreak3);
// adding to the DOM
document.body.appendChild(ulElement);Node.textContent property
// adding text node using appendChild
var text = document.createTextNode('Warning');
liElement1.appendChild(text);
// adding text node using textContent property
liElement1.textContent = 'Warning';Writing
var ulElement = document.createElement('ul');
// creating and appending nodes
...
ulElement.textContent; // "\nWarning\n\n"
Reading
<ul>
<li>Warning</li>
<li><!-- Empty node --></li>
</ul>Node.innerHTML property
var html =
"<div>Some text here</div>"
+ "<ul>"
+ " <li>Warning</li>"
+ " <li><!-- empty node --></li>"
+ "</ul>"
document.body.innerHTML = html;Writing
Reading
Gotchas
var name = "<img src=x onerror=alert(1)>";
el.innerHTML = name; // shows the alertdocument.body.innerHTML = "<div> & < > </div>";
document.body.innerHTML; // "<div> &-amp; &-lt; &-gt; </div>"Node.insertBefore method
<body>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
</ul>
</body>Initial html
Appending `div` element as the last child of the body
Appending `div` element before the `ul` element
var div = document.createElement('div');
div.innerText = 'I am appended before';
document.body.insertBefore(div, ul);var ul = document.createElement('ul');
ul.innerHTML =
"<li>Warning</li><li><!-- empty node --></li>"
document.body.appendChild(ul);<body>
<div>I am appended before</div>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
</ul>
</body>var div = document.createElement('div');
div.innerText = 'I am appended at the bottom';
document.body.insertBefore(div, null);<body>
<div>I am appended before</div>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
</ul>
<div>I am appended at the bottom</div>
</body>Inserting the same element multiple times
<body>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
</ul>
</body>Initial html
.cloneNode(deep)
Appending `div` element
var div = document.createElement('div');
div.innerText = 'I am div';
document.body.appendChild(div);
ul.appendChild(div);
ul.appendChild(div);
var ul = document.createElement('ul');
ul.innerHTML =
"<li>Warning</li><li><!-- empty node --></li>"
document.body.appendChild(ul);<body>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
<div>I am div/div>
</ul>
</body>ul.appendChild(div.cloneNode(true));<body>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
<div>I am div</div>
<div>I am div</div>
</ul>
</body>deep - true if the children of the node should also be cloned
DocumentFragment
<body>
<ul></ul>
</body>Initial html
Appending `li` elements using fragment
var fragment = document.createDocumentFragment();
var li1 = document.createElement('li');
var li2 = document.createElement('li');
li1.innerText = 'Warning';
li2.innerText = '<!-- empty node -->';
fragment.appendChild(li1);
fragment.appendChild(li2);
ul.appendChild(fragment);var ul = document.createElement('ul');
document.body.appendChild(ul);<body>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
</ul>
</body>Traversing
Tree like structure
<html>
<head>
<title>Example document</title>
</head>
<body>
<div>Some text here</div>
<ul>
<li>Warning</li>
<li><!-- empty node --></li>
</ul>
</body>
</html>
Global references (shortcuts)
Reference to root element
Reference to body element
Reference to document
var document = window.document;
document.nodeName; // #document
document instanceof Node; // true
document.nodeType === Node.DOCUMENT_NODE; // truevar rootElement = document.documentElement;
rootElement.nodeName; // HTML
rootElement instanceof HTMLElement; // true
rootElement.nodeType === Node.ELEMENT_NODE; // truevar bodyElement = document.body;
bodyElement.nodeName; // BODY
bodyElement instanceof HTMLElement; // true
bodyElement.nodeType === Node.ELEMENT_NODE; // trueReference to head element
var headElement = document.head;
headElement.nodeName; // HEAD
headElement instanceof HTMLElement; // true
headElement.nodeType === Node.ELEMENT_NODE; // trueNode Traversal functions

parentNode
previousSibling
nextSibling
Parents and neighbours
Childrens
Element Traversal functions

parentElement
previousElementSibling
nextSiblingParents and neighbours
Childrens
var ulElement = document.createElement('ul');
var liElement1 = document.createElement('li');
var liElement2 = document.createElement('li');
var pElement1 = document.createElement('p');
var lineBreak1 = document.createTextNode('\n');
var lineBreak2 = lineBreak1.cloneNode(true);
var lineBreak3 = lineBreak1.cloneNode(false);
var text = document.createTextNode('Warning');
var comment = document.createComment('Empty node');
// appending elements
liElement1.appendChild(text);
liElement2.appendChild(comment);
liElement2.appendChild(pElement1);
liElement2.appendChild(text);
pElement1.setAttribute('id', 'bar');
ulElement.appendChild(lineBreak1);
ulElement.appendChild(liElement1);
ulElement.appendChild(lineBreak2);
ulElement.appendChild(liElement2);
ulElement.appendChild(lineBreak3);
// adding to the DOM
document.body.appendChild(ulElement);
var body = document.body,
bar = document.getElementById('bar');
console.log(bar.nextSibling); // "Warning" {Node}
console.log(bar.nextElementSibling); // null
console.log(bar.previousSibling); // <!--Empty node--> {Node}
console.log(bar.previousElementSibling); // null
console.log(bar.parentElement); // li {Node}
console.log(bar.parentNode); // li {Node}
console.log(bar.parentElement.parentElement.parentElement.parentElement.parentElement) //null
console.log(bar.parentElement.parentNode.parentNode.parentNode.parentNode) //#document {Node}
var li = bar.parentNode;
console.log(li.children); // [<p id="bar"></p>]
console.log(li.childNodes); // [<!--Empty node-->, <p id="bar"></p>, "Warning"]
console.log(li.firstChild); //?
console.log(li.firstElementChild); //?
console.log(li.lastChild); //?
console.log(li.lastElementChild); //?
Fancier way to traverse

The main difference between these two interfaces is that the TreeWalker presents a tree-oriented view of the nodes in a subtree, rather than the iterator's list-oriented view.
In other words, an iterator allows you to move forward or back, but a TreeWalker allows you to also move to the parent of a node, to one of its children, or to a sibling.
according to
var node,
iterator = document.createNodeIterator(
document,
NodeFilter.SHOW_ELEMENT,
function (node) {
return node.nodeName === ‘p’ ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
}
);
while(node = iterator.nextNode()) {
console.log(node);
}var treeWalker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_ELEMENT,
{
acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; }
},
false
);
nodeFilter = treeWalker.filter; // document.body in this casenodeIterator
treeWalker
Modifying
Manipulating attributes
var input = document.createElement('input');
input.hasAttribute("disabled"); // falseChecking if attribute is present
Adding attribute or changing attribute value
input.getAttribute("disabled"); // "true"Removing attribute
input.setAttribute("disabled", "true");
input.hasAttribute("disabled"); // trueRetrieving attribute value
input.removeAttribute("disabled");
input.hasAttribute("disabled"); // falseManipulating classes
var div = document.createElement('div');
div.className; // ""
div.classList.add("class1");
div.className; // "class1"
div.classList.add("class2");
div.classList.add("class3");
div.className; // "class1 class2 class3"Adding class
Removing class
div.classList.contains("class1"); // false
div.classList.contains("class2"); // trueRetrieving class by index
div.classList.remove("class1");
div.className; // "class2 class3"Checking if class is present
div.classList.item(0); // "class2"Toggling class
div.classList.toggle("class1");
div.className; // "class1 class2 class3"
div.classList.toggle("class1");
div.className; // "class2 class3"Manipulating styles
var div = document.createElement('div');
div.getAttribute('style'); // null
div.style.setProperty('color', 'green');
div.style.display = 'none';
div.getAttribute('style'); // "color:green; display:none;"Adding inline style
Removing inline style
Reading inline style
div.style.removeProperty('color', 'green');
div.style.display = "";
div.getAttribute('style'); // nulldiv.style.setProperty('color', 'green');
div.style.getPropertyValue('color'); // "green"
div.styel.color; // "green"
div.style.cssText; // "color: green;"Reading computed style
var div = document.createElement('div');
document.body.appendChild(div);
div.style.getPropertyValue('display'); // ""
window.getComputedStyle(div).getPropertyValue('display'); // "block";with CSSStyleDeclaration
Reading applied styles
var div = document.createElement('div');
div.getAttribute('style'); // null
var style = window.getComputedStyle(div);
style.getProperty('display'); // "block";Adding style
Removing style
Reading style
div.style.removeProperty('color', 'green'); // what will be here if color is red?
div.style.display = "";
div.getAttribute('style'); // ""div.style.setProperty('color', 'green', 'important');
div.style.getPropertyValue('color'); // "green"
div.styel.color; // "green"
div.style.cssText; // "color: green;"CSSStyleDeclaration
Searching
getElementById
var div = document.createElement('div');
div.id = 'para1';
document.body.appendChild(div);
var foundDiv = document.getElementById('para1');
div === foundDiv; // trueSearching elements in the DOM
Searching elements in the memory
var div = document.createElement('div');
div.id = 'para1';
var foundDiv = document.getElementById('para1');
foundDiv === null; // truegetElementByClassName
var HTMLCollection = document.getElementsByClassName('searchable');
for (var i=0; i < HTMLCollection.length; i++) {
console.log(HTMLCollection[i].nodeName);
}
// 'DIV'
// 'SPAN'Searching elements in the DOM
<body>
<div class="searchable"></div>
<div class="non-searchable"></div>
<span class="searchable"></span>
</body>HTMLcollection is live
var div = HTMLCollection[0];
div.remove();
for (var i=0; i < HTMLCollection.length; i++) {
console.log(HTMLCollection[i].nodeName);
}
// 'SPAN'getElementByTagName
var HTMLCollection = document.getElementsByTagName('div');
for (var i=0; i < HTMLCollection.length; i++) {
console.log(HTMLCollection[i].className);
}
// 'first'
// 'second'Searching elements in the DOM
<body>
<div class="first"></div>
<div class="second"></div>
<span class="third"></span>
</body>querySelectorAll
var div = nodeList[0];
div.remove();
for (var i=0; i < nodeList.length; i++) {
console.log(nodeList[i].textContent);
}
// This is div
// This is link
// This is spanSearching elements in the DOM
<div class="first">This is div</div>
<a href="http://google.com">This is link</a>
<span class="third">This is span</span>NodeList is not live
var nodeList = document.querySelectorAll('div, a[href="http://google.com"], .third');
for (var i=0; i < nodeList.length; i++) {
console.log(nodeList[i].textContent);
}
// This is div
// This is link
// This is spanquerySelector
Example 1
<div class="first">
<span>This is inner span</span>
</div>
<span>This is outer span</span>var element = document.querySelector('span');
element.textContent; // This is inner spanExample 2
<span>This is outer span</span>
<div class="first">
<span>This is inner span</span>
</div>var element = document.querySelector('span');
element.textContent; // This is outer spanRemoving
Node.removeChild method
var div = document.createElement('div');
document.body.appendChild('div');
// removing
var removed = document.body.removeChild(div);
removed === div; // truechildNode.remove method
var div = document.createElement('div');
document.body.appendChild('div');
// removing
div.remove();Events
Events
- mouse (onclick, oncontextmenu..)
- keyboard (onkeyup, onkeydown..)
- loading (load, unload..)
- selection API (selectstart, selectionchange)
- frame/Object Events (onscroll, onresize..)
- form (onblur, onfocus..)
- drag (ondrag, ondrop..)
- clipboard (oncopy, oncut..)
- media (onplay, onpause..)
- animation (animationstart, animationend..)
- transitionend
Types:
Add, remove events
elem.addEventListener( "click" , function() {
alert('Hey!')
});
elem.removeEventListener( "click" , function() { // will not remove EventListener
alert('Hey!')
});document.onclick = function(event) {
console.log(event);
console.log(event.type + " on " + event.currentTarget);
console.log(event.clientX + ":" + event.clientY);
}var sayHey = function (e) {
console.log("Hey ", e.type);
};
document.getElementById('button1').addEventListener("click", sayHey);
document.getElementById('button1').removeEventListener("click", sayHey);Page hooks
DOMContentLoaded
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM fully loaded and parsed");
});onload
The general idea is that window.onload fires when the document's window is ready for presentation and document.DOMContentLoaded fires when the DOM tree (built from the markup code within the document) is completed.
window.onload = function() {
console.log('Page is ready for presentation');
}beforeunload/unload
window.onbeforeunload = function() {
return "Data is not saved, Are you sure you want to exit?";
};
Event Flow
So how it works?:
- При наступлении события – элемент, на котором оно произошло, помечается как «целевой» (event.target).
- Далее событие сначала двигается вниз от корня документа к event.target, по пути вызывая обработчики, поставленные через addEventListener(...., true).
- Далее событие двигается от event.target вверх к корню документа, по пути вызывая обработчики, поставленные через on* и addEventListener(...., false).
Каждый обработчик имеет доступ к свойствам события:
- event.target – самый глубокий элемент, на котором произошло событие.
- event.currentTarget (=this) – элемент, на котором в данный момент сработал обработчик (до которого «доплыло» событие).
- event.eventPhase – на какой фазе он сработал (погружение =1, всплытие = 3).
Shadow DOM
Simple it is..
Shadow DOM fixes CSS and DOM. It introduces scoped styles to the web platform
<html>
<head></head>
<body>
<p id="hostElement"></p>
<script>
// create shadow DOM on the <p> element above
var shadow = document.querySelector('#hostElement').attachShadow();
</script>
</body>
</html>Create Shadow DOM
What else?
Standarts

Drafts

Copy of DOM
By Nicholas Sorokin
Copy of DOM
- 1,646