Lecture 6

DOM and Events

Please read, and work with:

Chapter 6 and

A. Leftovers #2 and #3

Q&A

menti.com 

Document Object Model

DOM

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>

HTML elements as

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">

JAVASCRIPT OBJECTS

var img = {
    tagName: "img",
    id: "logo",
    src: "images/logo.png",
    alt: "JU logo",
    width: "100"
}

To spice it up, 

The browser also have parent objects linked 

An Element Object

HTMLElement

Element

finding things in the dom

There are multiple ways to find elements:

document METHODS:
getElementById
getElementsByClassName
getElementsByTagName
getElementsByName
querySelector
querySelectorAll

Element PROPERTIES:
parentElement
children
firstElementChild 
lastElementChil

finding things in the dom

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.

finding things in the dom

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

finding things in the dom

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

TRAVERSING the DOM

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.

for Parent elements

Properties

mom.childElementCount -> number
mom.children -> array of elementObjects
mom.firstElementChild -> elementObject
mom.lastElementChild -> elementObject

 

methods

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>

for child elements

Properties

child.previousElementSibling

child.nextElementSibling

child.parentElement

methods (experimental)

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

Try it

Go to https://kohlin.net/dom.html 

  1. In the Console, get the img element
  2. What is the alt attribute for the image?
  3. What is the parent element?
  4. Does it have a sibling?

finding things in the dom

changing css styles of elements

<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:""...}

changing css styles of elements

<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";

Getting text from elements

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

setting text of an element

<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">
&lt;p&gt; This is &lt;em&gt;new&lt;/em&gt; content &lt;/p&gt;
</div>

original state

after change

setting text of an element

<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>

setting text of an element

<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>

creating new elements

var navTag = document.getElementById("menu");

var ulTag = document.createElement("ul");
navTag.appendChild(ulTag);

document.createElement(tagString)

parent.appendChild(element)

Adding attributes

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>

creating many new elements


for (var i=1; i<=5; i++) {
 var tempLi = document.createElement("li");
    
 tempLi.setAttribute("id", "item" + i);

 ulTag.appendChild(tempLi);
}

Removing elements #1


var parent = document.getElementById("menu");

var child = parent.children[0];
//or document.querySelector("#menu ul")

parent.removeChild(child)

parent.removeChild(element)

Removing elements #2


var children = document.querySelector("#menu li");

for (var i = 0; i < children.length; i++) {
    children[0].remove()
}

child.remove()

Try it out

before we go on...

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:

Events?

Go here