Javascript : DOM

Javascript : DOM

Seventh article in my javascript adventure and the topic today is the manipulation of an html page. As usual, this article is written in a brief, code-first style and essentially targets developers.

The DOM is a hierarchical tree of objects representing the structure of current html file.

                         Document
                            |
                          Root (<html>)
                            |
         ---------------------------------------                   
         |                                     |
    Element (<head>)                      Element (<body>)
         |                                     |
    Element (<title>)                 ---------------------
         |                            |                   |
    Text ("My page")             Element(<h1>)       Element(<a>)------Attribute("href")
                                      |                   |                 
                                  Text ("Title")    Text ("Link")

Javascript lets you add/edit/delete any html element, attribute, text in the page.
Besides, with javascript you can react to html events and event create new ones if needed.

Note: each element of the graph is a node

Methods

// 'document' is a global object, always accessible
// 'getElementById' is the most common way of accessing an html element
// 'innerHTML' let you access the content of an html element
let element = document.getElementById("demo");

// An html element offers the following interface
// 'innerHTML' let you access the content of an html element
element.innerHTML = "New text";
// .[attribute] to change any attribute value
element.id = "newId";
// .style.[property] to change any style property
element.style.margin_left = "1px";
// 'setAttribute' to change an attribute's value or add new attributes
element.setAttribute("style", "background-color: blue;");
// You can dynamically add event listeners to an element (does not overwriting existing ones)
element.addEventListener("click", doSomething)
// or remove them
element.removeEventListener("click", doSomething)

// The following returns a list of all <p> elements
document.getElementsByTagName("p");

// The following returns a list of all tags with class="header-elements"
document.getElementsByClassName("header-elements");

// The following creates an html element
document.createElement("div");

// The following creates an html element
document.removeChild("div");

// The following appends an html element to current node
document.appendChild("p");

// The following replaces an html element with a new one
document.replaceChild("p", "div");

// The following replaces an html element with a new one
document.createTextNode("Content of any element.Place me with appendChild(node)");

// Get elements by their css selector
// https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
document.querySelector(".myclass");

// The following directly writes into the html output stream
// Never use after the document is loaded, it will overwrite the document
document.write("<div>Hello world</div>");

Events

// Attach event handlers (functions) to the events of interest
document.document.getElementById("myButton").onclick = onButtonClick;

function onButtonClick() {
  console.log("Button clicked");
}

Commonly used events

// 'onload' and 'onunload' are triggered when a user enters and leaves a page.
// They are generally used to check user's web browser type or to deal with cookies
<body onload="checkCookies()">
// 'onchange' is usually used in combination with validation of input fields
// When the content of the input changes, 'reevaluate' is called
<input type="text" id="fname" onchange="reevaluate()">
// 'onmouseover' and 'onmouseout' detect the user's cursor
<p onmouseover="this.innerHTML='On me'">
   onmouseout="this.innerHTML='On outside'"> 
    Some text
</p>
// 'onmousedown' and 'onmouseup' detect the user's clicks
<p onmousedown="this.innerHTML='Clicking'">
   onmouseup="this.innerHTML='Click released'"> 
    Some text
</p>

Event propagation

<div>
  <p></p>
</div>

When adding an event listener you can specify how the events are propagated. You have 2 options:

  • bubbling : the inner element is called first, then the outer
  • capturing : the outer element is called first, then the inner
p_element.addEventListener("click", runA, false); // bubbling
p_element.addEventListener("click", runA, true); // capturing

Properties

Below is the list of html properties that are accessible in HTML5.

// get all <a name=""> elements (if no name attribute, it won't be returned)
document.anchors;
// absolute base uri of the document
document.baseURI;
// returns <body>
document.body;
// returns the document's cookie
document.cookie;
// returns document doctype
document.doctype;
// returns <html>
document.documentElement;
// returns the mode used by the browser
document.documentMode;
// uri of the document
document.documentURI;
// domain name of the document server
document.domain;
// returns all <embed> elements
document.embeds;
// returns all <form> elements
document.forms;
// returns all <head> elements
document.head;
// returns all <img> elements
document.images;
// returns the DOM implementation
document.implementation;
// document's encoding (i.e. UTF(, ...)
document.inpuEncoding;
// returns document's last update time
document.lastModified;
// returns all <area> and <a> that have an href
document.links;
// returns the loading status of the document
document.readyState;
// returns the uri of the referrer (the linking document)
document.referrer;
// returns all <script> elements
document.scripts;
// returns if error checking is enforced
document.strictErrorChecking;
// returns <title> element
document.title;
// returns the complete URL of the document
document.URL;

You can navigate the DOM from an element using the following properties:

// get parent element
element.parentNode;
// get array of child elements
element.childNodes;
// get first child
element.firstChild;
// get last child
element.lastChild;
// if the element is one the child nodes, you can select next one (sibling)
element.nextSibling;
// same as before but to select the previous sibling
element.previousSibling;

You access any html object's metadata as well:

// if obj is an element, nodeValue is null
// if obj is an attribute, nodeValue is the attribute value
// if obj is a text, nodeValue is the text (same as innerHTML for an element)
obj.nodeValue;

// if obj is an element, nodeName is the tag name
// if obj is an attribute, nodeName is the attribute name
obj.nodeName;

// if obj is an element, nodeType is 1
// if obj is an attribute, nodeType is 2
// if obj is a text, nodeType is 3
obj.nodeType;

Forms

In html, you can natively declare forms.

<form name="myForm" method="post">
  Name: <input type="text" name="fname">
  <input type="submit" value="Submit">
</form>

You can use javascript to validate user inputs:

<form name="myForm" onsubmit="return validateForm()" method="post">
  Name: <input type="text" name="fname">
  <input type="submit" value="Submit">
</form>

<script>
function validateForm() {
  let x = document.forms["myForm"]["fname"].value;
  if (x == "") {
    alert("Name must be filled out");
    return false;
  }
}
</script>

Animation

You can write custom animations entirely in javascript.

// when called, this function will move the element (id="animate")
// pixel by pixel on x and y axes until from position 0,0 to 350,350
// with intervals of 5 milliseconds
function myMove() {
  let id = null;
  const elem = document.getElementById("animate");
  let pos = 0;
  clearInterval(id);
  id = setInterval(frame, 5);
  function frame() {
    if (pos == 350) {
      clearInterval(id);
    } else {
      pos++;
      elem.style.top = pos + 'px';
      elem.style.left = pos + 'px';
    }
  }
}

Window

All global javascript objects, functions and variables are member of the window object.

window.document.getElementById("header");

window has properties that might be useful:

// Inner height of the browser window in px
window.innerHeight;
// Inner width of the browser window in px
window.innerWidth;

but also methods:

// Open a new window
window.open();
// Close current window
window.close();
// Move current window
window.moveTo();
// Resize current window
window.resizeTo();

Screen

The property window.screen gives information about the visitor's screen in pixels.

screen.width;
screen.height;
// same as width/height, minus interface features like windows taskbar
screen.availWidth;
screen.availHeight;
// Number of bits used to display a color
screen.colorDepth;
screen.pixelDepth;

Location

The property window.location provides details about URL of current page.

// URL
window.location.href;
// Domain name of web host
window.location.hostname;
// Filepath of html page
window.location.pathname;
// http or https
window.location.protocol;
// Navigate to a new document
window.location.assign("https://www.google.com");

History

The property window.history contains the browsers history.
history can be used (without window prefix).

// Navigate back
history.back();
// Navigate forward
history.forward();

The property window.navigator contains information about visitor's browser.
navigator can be used (without window prefix).

// true if cookies are enabled
navigator.cookieEnabled;
// browser platform (OS)
navigator.platform;
// browser's language
navigator.language;
// browsing app version
navigator.appVersion;

Popups

All popups are part of window but can bue used without prefix.

// Send information to user
alert("Click Ok to close me");
// Get user authorization for something
confirm("Click Ok or Cancel to continue");
// Get user input (Ok and Cancel are displayed)
prompt("What's your name", "Default name");

Cookies

A cookie is a client-side file used to store user data for a browsing session.
The file is deleted when the browser is closed.
It stores key/value pairs.

This file is added to the requests made to remote servers.
Cookies must be enabled on the browser to use the following features.

// Create or edit a cookie
// The cookie has 3 parameters
// username: name of the user
// expiration date : [Optional] After the date, the cookie is no longer valid 
// path: [Optional], default:/ (points to current page)
document.cookie = "username=John Smith; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";
// Delete by setting the expiration date to a past date
document.cookie = "username=John Smith; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

// cookie is not a string. You can actually have several cookies at the same time
document.cookie = "username=Maria Cray; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";
document.cookie = "username=Mike Still; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/";

console.log(document.cookie); // displays: cookie1=username=Maria Cray;...; cookie2=username=Mike Still;...;