Document Object Model
This article is the seventh part of Week of Web(#WOW). If you don’t know what #WOW is here’s a card to it.
In this article, we will learn how HTML documents are compiled by JavaScript to create a Document Object Model and how could we use it to make our website interactive.
What is DOM?
It’s basically a structured representation of your HTML document. It is a tree of nodes (or elements) created by the browser. Javascript could be used to manipulate the DOM and its elements.
DOM is object-oriented that means each node has its own property and methods that we can change, add and remove.
Setting up files to learn the Document Object Model
Now to get started with the Document Object Model we will have to create an HTML document and have some styles in it as well. Don't worry we have these created for you already.
Keep both these files in the same folder and then create a new file called dom.js and link it to domStarter.html using the script tag at the end of the body.
Explaining the document object
This document object could be accessed by using the following command.
console.dir(document);
This displays all the properties of your created HTML document converted in the form of an object literal in JavaScript.
To access these properties you can use the dot operator. These are a few examples.
console.log(document.domain);
console.log(document.URL);
console.log(document.title);
console.log(document.title);
console.log(document.doctype);
console.log(document.head);
console.log(document.body);
console.log(document.all);
console.log(document.all[16]);
You could also change any property by using the assignment operator
document.title = "DOM Manipulation";
Selectors
We can assign object key values to a variable in our code by selecting them and then we perform operations on them.
Getting element by id
Let's select our heading which has an id of header-title
and store it in a variable. So that we don't have it write the statement to select again when we have to make other changes.
let headerTitle = document.getElementById("header-title");
Now after selecting we can perform operations on this object.
The textContent Method
The textContent Method is used to display the content of an element without considering the styles written for it
console.log(headerTitle.textContent);
// Things To Do, Get things done!
The innerText Method
The innerText Method is used to display the content of an element while considering the styles written for it
console.log(headerTitle.innerText);
//Things To Do
The innerHTML Method
The innerHTML Method is used to display the content of an element with nested HTML inside it.
console.log(headerTitle.innerHTML);
//Things To Do<span style="display: none">, Get things done!</span>
Now everything makes sense right? The statement “Get things done!” was hidden becuase of the “display: none” style.
The style Method
The style method could be used to change the style of an HTML element.
The syntax is
selectedElement.style.attribute = "value";
For example,
headerTitle.style.borderBottom = "3px solid green";
headerTitle.style.color = "red";
headerTitle.style.backgroundColor = "yellow";
Getting elements by className
Now we know that classes can occur many times and ids are unique. So when we have to select a class it should select all the occurrences of that class.
let taskText = document.getElementsByClassName("task-text");
console.log(taskText);//HTMLCollection(5) [span.task-text, span.task-text, span.task-text, //span.task-text, span.task-text]
//0: span.task-text
//1: span.task-text
//2: span.task-text
//3: span.task-text
//4: span.task-text
//length: 5
//__proto__: HTMLCollection
It gives us an array of all the occurrences.
Now to select an individual element in an array we use
console.log(taskText[1]);
//<span class="task-text">Go on a Run</span>
And then we can perform all the operations on it as we did with ids
taskText[1].textContent = "Go on a Walk";
taskText[1].style.fontWeight = "bold";
To change the properties of all the occurrences of that class we can't directly select it.
taskText.style.backgroundColor = "#f4f4f4";
To select all the elements we will have to loop through them like this
for (let i = 0; i < taskText.length; i++) {
taskText[i].style.backgroundColor = "#f4f4f4";
}
Getting elements by tag name
Similarly, we can get all occurrences of HTML tags by their tag names and perform operations on them.
let list = document.getElementsByTagName("li");
console.log(list);
//HTMLCollection(5) [li.task, li.task, li.task, li.task, li.task]
//0: li.task
//1: li.task
//2: li.task
//3: li.task
//4: li.task
//length: 5
//__proto__: HTMLCollection
QuerySelector
All the above selections could be done by a single command called querySelector.
let headerTitle = document.querySelector("#header-title");
console.log(headerTitle);
//<h1 id="header-title">...</h1>let taskText = document.querySelector(".task-text");
console.log(taskText);
//<span class="task-text">Read an article</span>
QuerySelectorAll
But here if we notice querySelector selects only the first occurrence of a class. To fix this we use querySelectorAll method
let taskTextAll = document.querySelectorAll(".task-text");
console.log(taskTextAll);
//NodeList(5) [span.task-text, span.task-text, span.task-text, //span.task-text, span.task-text]
//0: span.task-text
//1: span.task-text
//2: span.task-text
//3: span.task-text
//4: span.task-text
//length: 5
//__proto__: NodeList
Creating a New Element
Now let us learn how to create a new HTML element
Creating an element
let newDiv = document.createElement("div");
console.log(newDiv);
// <div></div>
Assigning a class name to the element
newDiv.className = "hello-class";
console.log(newDiv);
//<div class="hello-class"></div>
Assigning an id to the element
newDiv.id= "hello-id";
console.log(newDiv);
//<div id="hello-id"></div>
Setting an Attribute to the element
newDiv.setAttribute("title", "Hello Div");
console.log(newDiv);
//<div title="Hello Div"></div>
Adding content to the element
let newDivText = document.createTextNode("Have a Nice Day");
newDiv.appendChild(newDivText);
console.log(newDiv);
//<div>Have a Nice Day</div>
Inserting the element into DOM
let container = document.querySelector(".container");
container.insertBefore(newDiv, list);
Event Listener
Let's say we have a function defined like this
const buttonClick = () => {
console.log("Button Clicked");
};
And we want it to be executed when the button is clicked. To do this we select a button and add an event listener to it like this
Add Event Listener
let button = document.querySelector("#button");
button.addEventListener("click", buttonClick);
So when the button is clicked the buttonClick function is executed. Similarly we have many other event listeners for mouse and keyboard.
Mouse Event Listeners
These are some other mouse event listeners. The property name is evident enough to know when they are triggered.
button.addEventListener("dblclick", buttonClick);
button.addEventListener("mousedown", buttonClick);
button.addEventListener("mouseup", buttonClick);
button.addEventListener("mouseenter", areaEnter); //parent element
button.addEventListener("mouseleave", areaEnter);
button.addEventListener("mouseover", areaEnter); //inner element
button.addEventListener("mouseout", areaEnter);
button.addEventListener("mousemove", areaEnter);
Keyboard Event Listeners
We could add event listeners to an input text field and on listening to any key it could execute a runEvent function (example).
let inputTask = document.querySelector('input[type="text"]');
let form = document.querySelector("form");
inputTask.addEventListener("keydown", runEvent);
inputTask.addEventListener("keyup", runEvent);
inputTask.addEventListener("keypress", runEvent);
Input Event Listener Types
Similarly, any input field could also have the following listeners
inputTask.addEventListener("focus", runEvent);
inputTask.addEventListener("blur", runEvent);
inputTask.addEventListener("cut", runEvent);
inputTask.addEventListener("paste", runEvent);
inputTask.addEventListener("input", runEvent);
inputTask.addEventListener("change", runEvent);
inputTask.addEventListener("submit", runEvent);
This much information should be enough. Now let's apply these concepts to our ToDo list application.
Adding background image switcher to ToDo list application
Head over to the public folder of our repository and add a couple of background images.
Rename these images as background1, backgorund2, background3 and background4.
Create a folder named img
inside the public folder and move all these images here.
Your folder structure should look something like this
Now create app.js
file in the public folder and link it to index.html
Now let’s add a background selector in our HTML document and style it.
Let's add this division to the end of our HTML file.
<div id="background-selector">
<span class="background" id="bg1"></span>
<span class="background" id="bg2"></span>
<span class="background" id="bg3"></span>
<span class="background" id="bg4"></span>
</div>
Let's add these properties to our CSS file
#background-selector {
position: absolute;
top: 90%;
left: 90%;
}.background {
display: inline-block;
border: 2px solid grey;
margin: 2px;
width: 20px;
height: 20px;
}#bg1 {
background-color: #0f4721;
cursor: pointer;
}
#bg2 {
background-color: #c7b18a;
cursor: pointer;
}
#bg3 {
background-color: #f42628;
cursor: pointer;
}
#bg4 {
background-color: #b3c3d3;
cursor: pointer;
}
Now let's write some DOM Manipulations in our app.js file
First, we select all the object key values we need.
let bgButton1 = document.querySelector("#bg1");
let bgButton2 = document.querySelector("#bg2");
let bgButton3 = document.querySelector("#bg3");
let bgButton4 = document.querySelector("#bg4");
let body = document.body;
Now let's write some functions which will assign the background image on execution.
const changeBg1 = () => {
body.style.backgroundImage = `url("./img/background1.jpg")`;
};
const changeBg2 = () => {
body.style.backgroundImage = `url("./img/background2.jpg")`;
};
const changeBg3 = () => {
body.style.backgroundImage = `url("./img/background3.jpg")`;
};
const changeBg4 = () => {
body.style.backgroundImage = `url("./img/background4.jpg")`;
};
Now add Event listeners to our background selectors
bgButton1.addEventListener("click", changeBg1);
bgButton2.addEventListener("click", changeBg2);
bgButton3.addEventListener("click", changeBg3);
bgButton4.addEventListener("click", changeBg4);
This is how it should look on clicking the background selectors
And Voila the background switchers are ready!
With this, we are done with the Frontend Architecture!
In the next article, we will learn how to design a Backend Architecture. And we will get started with Node.js. Using these we will store the values of our To-Do List Application to Database such that our application will start functioning as intended.
This is Vinayak Tekade from Coder’s Capsule in collaboration with Developer Student Clubs Amrita School of Engineering Bengaluru signing off.
Follow me on LinkedIn and Twitter.
Looking forward to learn, teach and grow together. Check us out on Instagram for more similar content.