DOM and Events
Please read, and work with:
Chapter 6 and
A. Leftovers #2 and #3
Q&A
menti.com
a model to describe the HTML document as a JavaScript object
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script>console.log("Hello world")</script>
</head>
<body>
  <h1></h1>
  <div id="entry1">
    <h2>Hello</h2>
    <p>My name is:</p>
    <p></p>
  </div>
</body>
</html>| attribute/property | value | 
|---|---|
| id | logo | 
| src | images/logo.png | 
| alt | JU logo | 
| width | 100 | 
var img = {
    tagName: "img",
    id: "logo",
    src: "images/logo.png",
    alt: "JU logo",
    width: "100"
}
<img id="logo" src="images/logo.png" alt="JU logo" width="100">var img = {
    tagName: "img",
    id: "logo",
    src: "images/logo.png",
    alt: "JU logo",
    width: "100"
}The browser also have parent objects linked
An Element Object
HTMLElement
Element
There are multiple ways to find elements:
document METHODS:
getElementById
getElementsByClassName
getElementsByTagName
getElementsByName
querySelector
querySelectorAll
Element PROPERTIES:
parentElement
children firstElementChild lastElementChil
Find the Element By searching for Its ID attribute
document.getElementById("main-menu") 
// <nav id="main-menu">...</div><header>
  <nav id="main-menu"> <!-- this and all it's children -->
    <ul>
      <li>home</li>
      <li>about</li>
    </ul>
  </nav>
</header>document.getElementById() returns the element that match the argument passed in.
First match for a CSS selector
document.querySelector("nav ul li.current") // <li>home</li><nav>
  <ul>
    <li class="current">home</li>
    <li>about</li>
  </ul>
</nav>nav ul li.current { /* uses the same logic as CSS*/
    color: red;
}document.querySelector() returns the first element that match the query
All elements that match the CSS selector
var li = document.querySelectorAll("li") // [<li>,<li>]
li[1] // <li>about</li><nav>
  <ul>
    <li class="current">home</li>
    <li>about</li>
  </ul>
</nav>document.querySelectorAll() returns all elements that match the query as an array-like data structure
var mom     = el.parentElement; // <ul>...</ul>
var granny  = mom.parentElement; // <nav>...</nav>
var brother = mom.lastElementChild // <li>about</li>
var me      = mom.children[0] // <li class="current">home</li><nav>
  <ul>
    <li class="current">home</li>
    <li>about</li>
  </ul>
</nav>var el = document.querySelector(".current"); //<li class="current">home</li>1.
2.
mom.childElementCount -> number mom.children -> array of elementObjects mom.firstElementChild -> elementObject mom.lastElementChild -> elementObject
mom.appendChild(newChild) 
mom.removeChild(oldChild)  
mom.replaceChild(newChild, oldChild)
mom.insertBefore(newChild, currentChild)
var mom = document.querySelector('ul'); 
var foreign = document.querySelector('.other-mother');
var kidCount = mom.childElementCount;    // 3
var kidList = mom.children;              // [<li>, <li>, <li>]
var adoptee = foreign.firstElementChild; // <li>water</li>
var adoptee2 = foreign.lastElementChild; // <li>fire</li>
mom.insertBefore(adoptee, kidList[0]);
mom.appendChild(adoptee2);
mom.replaceChild(kidList[3], kidList[2]);
foreign.removeChild(foreign.lastElementChild); <ul>
  <li>Ben</li>
  <li>Lucy</li>
  <li>Cory</li>
</ul><ul class="other-mother">
  <li>Anna</li>
  <li>Kalle</li>
  <li>David</li>
</ul>child.previousElementSibling
child.nextElementSibling
child.parentElement
ChildNode.remove() -> remove me ChildNode.before(sibling) -> add sibling before me ChildNode.after(sibling) -> add sibling after me ChildNode.replaceWith(newChild) -> replace me with newChild
Go to https://kohlin.net/dom.html
<html>
<body>
  <div style="width:100px; height:100px; background-color:orange;">
  </div>
</body>
</html>| property | value | 
|---|---|
| width | 100px | 
| height | 100px | 
| backgroundColor | orange | 
| border | none (default) | 
In the Document Object Model, an elements' style property is not a string value.
Instead it's an object containing all CSS properties as object properties.
{backgroundColor: "orange", height:"100px", width: "100px", border:""...}<html>
<body>
  <div id="box" style="width:100px; height:100px; background-color:orange;">
  </div>
</body>
</html>var box = document.getElementById("box");
box.style.width = "50px";
box.style.height = "200px";
box.style.backgroundColor = "green";
// Or, you can read/write the entire HTML style attribute as one string:
box.style.cssText = "width:50px; height:200px; background-color:green";innerText & innerHTML
<p> Hello <span style="display:none">there my friend. Welcome to the </span> world </p>
<script>
var p = document.querySelector('p');
</script>| property | result | 
|---|---|
| p.innerHTML | <p> Hello <span style="display:none">there my friend. Welcome to the </span> world </p> | 
| p.innerText | Hello world | 
| p.textContent | Hello there my friend. Welcome to the world | 
<div id="demo">
<h1>Existing content</h1>
</div>var div = document.getElementById('demo');
div.innerText = '<p> This is <em>new</em> content </p>';Existing content
<p> This is <em>new</em> content </p>
HTML
HTML
Browser output
Browser output
Using innerText
<div id="demo">
            
            
<p> This is <em>new</em> content </p>
            
            
</div>
        
        
original state
after change
<div id="demo">
<h1>Existing content</h1>
</div>var div = document.getElementById('demo');
div.innerHTML = '<p> This is <em>new</em> content </p>';Existing content
HTML
HTML
Browser output
Browser output
Using innerHTML
original state
after change
This is new content
<div id="demo">
<p> This is <em>new</em> content </p>
</div><div id="demo">
<h1>Existing content</h1>
</div>var div = document.getElementById('demo');
div.insertAdjacentHTML('beforeEnd', '<p> This is <em>new</em> content </p>'); // scroll down..
/* possible positions: 
beforeBegin 
 <div id="demo">
afterBegin 
 <h1>Existing content</h1>
beforeEnd
 </div>
afterEnd
*/Existing content
HTML
HTML
Browser output
Browser output
Using insertAdjacentHTML(position, text)
original state
after change
Existing content
This is new content
<div id="demo">
<h1>Existing content</h1>
<p> This is <em>new</em> content </p>
</div>var navTag = document.getElementById("menu");
var ulTag = document.createElement("ul");navTag.appendChild(ulTag);document.createElement(tagString)
parent.appendChild(element)
var navTag = document.getElementById("menu");
var ulTag = document.createElement("ul");navTag.appendChild(ulTag);element.setAttribute(property, value)
ulTag.setAttribute("class", "center-aligned");<nav>
  <ul class="center-align"></ul>
</nav>
for (var i=1; i<=5; i++) {
 var tempLi = document.createElement("li");
    
 tempLi.setAttribute("id", "item" + i);
 ulTag.appendChild(tempLi);
}
var parent = document.getElementById("menu");
var child = parent.children[0];
//or document.querySelector("#menu ul")
parent.removeChild(child)parent.removeChild(element)
var children = document.querySelector("#menu li");
for (var i = 0; i < children.length; i++) {
    children[0].remove()
}child.remove()
Passing a function as an argument...
function surprise( callback ) {
  var msg = "Ta daaah!";
  callback(msg);
}
surprise(alert);
surprise(prompt);...is like passing instructions to another function
function surprise( callback ) {
  var msg = "Ta daaah!";
  callback(msg);
}
surprise( function(msg) { document.write(msg); } );It doesn't need to be a named function: