DOM(Document Object Model) | Indepth DOM Tutorial
Tags: javascript, beginners, webdev, html
Published: 2020-08-23 23:19:37

Good day, I am Emmanuel Onah and today we will be talking about the DOM but before I proceed, I will like to tell you a little story that I think could give you a general overview of the DOM before we proceed.

**THE STORY**: Ones upon a time, there was a king called the “DOM”(Deadly Opinionated Magician), this royal king allow people to live freely and commit all sort of maltreatment over the poor(e.g taking away what belongs to the poor). But ones an official report gets to that king(DOM), he allows the poor to do whatsoever they want with the people whose report were made(the offenders) e.g: eliminating of the offenders, rehabilitating or temporal punishment which keeps the offenders temporary away from associating with people in the community. And that was why the king was called the deadly opinionated magician who allows the deadly opinion of victims over the offenders in a twinkle of an eye THE END.

The above story is a summary of what the DOM does. Meanwhile, the DOM stands for Document Object Model.
___
Brief Secret of what you will learn in this tutorial: you will watch a practical explanation of the DOM and how it came about.

___
####TABLE OF CONTENT
1. DOM explanation
2. NODE explanation
3. Type of DOM Nodes
4. DOM Structure
5. Common DOM Methods and Properties(Note, these methods and properties are present in the DOM root object ”Window”)
6. NODE in detail
7. Common NODE properties and methods
8. HTMLCollection and NodeList
9. childNodes vs children property
10. Video Tutorial of The DOM
11. Bonus Tutorial (onload, DOMContentLoaded and defer)


___
### 1. DOM EXPLANATION:
**DOM**: The DOM is an acronym for Document Object Model. The DOM is an important sector of every web browser(it is present and can be viewed in every web browser by simply opening the devtools) which models our document(in our case its HTML) into the DOM window root-object of **DIFFERENT CATEGORIES OF NODES**. 

In a nutshell, the DOM is a mechanism built into the web browser that takes our document, turns it into 
**NODE_REPRESENTATION**(that is, everything in our Html document will be turned into object Nodes in our browser). And with the help of the DOM, we get to have a live representation of our HTML document and that’s why we get to make a change right from the javascript by targeting the DOM and it takes a simultaneous effect on our webpage.

Finally, whenever you hear about the DOM, don’t panic just recall that its an object(note, everything about js is an object including classes) full of props and methods that belong to our document + it has a representation of our HTML document in NODES format. I know I have mentioned NODE countless times, don’t panic we will talk about that in the next paragraph.
 
**DOM panel screengrab**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gz6y6ve6si9l1iech61r.png)


___
###2. NODE EXPLANATION
**NODE**: first and famous, I would like to give you a brief history of the NODE.
Node was a term used in the early days of telecommunication and networking where it was used to tag the point at which POWERING LINES intersects or terminate. Then as web development came into limelight and DOM was introduced, the term was adopted and this was used to classify every content of our webpage (e.g starting from your document itself(example of documents in our case is the **HTML** but there is still things like XML and …), elements, the text inside the element, comments and so on and so forth but I know the classification of DOM NODES ranges from 1 to 12 i.e we have 12 types of NODES as of when I wrote this article ).

So in a nutshell, everything you see on a webpage is called a NODE in the DOM and that’s one of the things the DOM does, it takes the buttons, images, h1..s, tables, Comments, excluding attributes, text, and so on and it turns each and every one of those web contents into NODES. 


**direct childNodes of your document Node**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u4hnkmq5oaea71q5ynxz.png)


___
###3. TYPES OF DOM NODE
We have 12 types of DOM Node in which 5 are deprecated and 7 are up and running. So if you might be wondering what deprecation is; **deprecation** is a term mostly used in programming to classify things that are not recommended to be used due to one thing or the other. For example, as a result, they are expensive to be used because of the effect they have on applications as such, the updaters of such program seize to keep upgrading or updating such things. **BUT** note that deprecated things still exist because of the probability that they are still being used in some products. Example of deprecated element in HTML are <marque>, <i> and...

**Nodes types and their explanation**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hmjb7uaehygah8f88ajt.png)

**Types of Node**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gwtxw20ro1sv4lgbhex9.png)


___
###4. DOM STRUCTURE
Before we head to the construction of the DOM Tree, I will like to notify you that the browser-DOM is built in such a way that it has different DOM interfaces with predefined attributes, this means that when the browser is creating the DOM it simply implements every interface of the DOM and that’s how all the possible properties and methods becomes present in our DOM even if our HTML document is empty.

*DOM structure*
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j0hvi6b6fv66pcgspwlg.png)


####EXPLANATION OF THE DOM STRUCTURE
**Object**: this is the root of a DOM Tree and in our case, it's the window object. Every other content of the DOM lies inside the window object.

**EventTarget**: this is simply an interface which provides us with the method we use for performing events ones it gets inherited by DOM Nodes(this inheritance are wrapped away from naked eyes but behind the hood inheritances in happening between Nodes and eventTarget interface for addEventListener or removeEventListener to be used) e.g addEventListener(),removeEventLister()…

**Node**: this interface is the one that holds the predefined types of NODES e.g COMMENT_NODE, ELEMENT_NODE….. and this is the interface that gets inherited when classifying NODE_TYPES

**Element**: This interface is the base class being inherited by all elements and this has different possible methods and properties an element can access(so available props and methods are based on elements).

**HTMLCollection**: this interface gets inherited when NODES children want to be created. It simply provides a collection of elements relative to one parent(note I said only elements like button,p… not nodes like COMMENT_NODE or TEXT_NODE...)
[More DOM Interface](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)


___
###5. COMMON DOM METHODS AND PROPS
Before I proceed to DOM properties, I will like to briefly explain what the heck is **Object property and Object Method**.

**Object property**: As we all know, everything in js is an object from function to the Jscript global environment itself. But inside an object, we can have object content that is just a plain **key-value pair** and this type of object-content are called object property e.g:
    const obj = {name:”Jerry”}

**Object method**: on the other hand, object method are basically functions inside an object as a content e.g:

    Const obj = {
      func1:()=>{},
      func2:function(){},
      func3(){}
  }

*Note*: either of this ways is correct for creating **object methods** but note that when dealing with binding or when trying to use the global object keyword**(this)** to access things at a certain scope, **this** keyword will fail in the context of arrow function and that is as a result of how javascript constructs **this** keyword behind the hood and this is something I will write a different article on.

####DOM PROPERTIES
**document**: is a DOM property(its called DOCUMENT_NODE) inside the window-root object and with **document** property you get to query your elements or do alot of thing like 
    document.querySelector('div');
    document.createElement('p');

####DOM METHODS
**alert**: is one of the DOM methods inside the window object.
So I will not spend much time on DOM properties and methods because we have a bunch of them and I just wanted to create awareness. Meanwhile, you can go to the console of your web browser and type window.(dot) and you will see all the properties and methods present in your **DOM root object**.


___
###6. NODE 
The NODE is a browser DOM interface and when inherited it helps to create different NODES out of our webpage. So as we discussed earlier, everything in our HTML document is turned into NODES and every node has a property or method attached to it (technically from every NODE an object is formed and the object for one NODE might defer from another NODE e.g with IMG_NODE(Mind you, all Element Nodes are classified as ElEMENT_NODE so when you see IMG_NODE or BUTTON_NODE I mean ELEMENT_NODE but for explanation purpose, I try to be explicit) you can access the *src* property, but with H1_NODE you can not access src because it's not present in the object created for that H1).


___
###7. COMMON NODE PROPERTIES AND METHODS

####NODE PROPERTIES
**Node.nodeType**: this property can be used to find out the nodeType of your element.e.g:     
    document.querySelector('h1').nodeType;//1: which is ELEMENT_NODE

**Node.childNodes**: this is best suitable when trying to return all the nested_node of a parent_node e.g when trying to return all the nodes of a div element. E.g:
    document.querySelector(‘div’).childNodes;

####NODE METHODS
**node.appendChild(TheNewlyCreatedNode)**: this method can be used to add a newly created node into a parentNode but at the last index (from the method-name, you can predict what it does which is; appending to the childNodes of a parent-node) e.g:

    const para = document.createElement(“p”);

    para.textContent = “Must you know the DOM or Javascript, rhetorical right?”;

    document.querySelector(“div”).appendChild(para);

**node.insertBefore()**: hmmm to me, I like to call this method the opposite of **appendChild()** because, technically we have **append()** to be an opposite of **prepend()** but unfortunately we have appendChild() but don’t have anything like **prependChild()**. But the only way to logically achieve the way **prependChild()** should work if it ever existed is to use **insertBefore()** node-method.With this method we are able to insert a newly created node at the very front or before the index of any targeted **childNode** of the referenced node. E.g:

    const para = document.createElement(‘p’);

    Para.textContent = “Code is fun when you think of it as a normal language you must learn constantly to get fluent in it”;

    const divWrapper = document.querySelector(“div”);

    divWrapper.insertBefore(para, divWrapper.childNodes[0]);

So basically what the above code does is, it goes to **divWrapper** in the DOM and for the fact that divWrapper has nested contents which in the DOM they are represented inside a NodeList similar to an array, it goes and inserts the **para** node at index 0 of the NodeList.

[More about Node methods and properties](https://developer.mozilla.org/en-US/docs/Web/API/Node)


___
###8. HTMLCollection and NodeList:

**HTMLCollection**: HTMLCollection is simply a collection of HTML elements that are relative to a specific parent_NODE e.g button elements, p elements, h1 elements...
**For Example**
    window.document.childNodes[2].children//this will produce HTMLCollection. The code simply says: go to document and from document get the childNode of the document present at index 2 then get the elements of that childNode.
    document.getElementByTagName('div');// this also means, got to document and get me all elements whose tag name is div.

**NodeList**: NodeList is a collection of all the Nodes relative to a specific parent(e.g ELEMENT_NODE,TEXT_NODE,COMMENT_NODE...)

####How TO GET A NODELIST AND HTMLCOLLECTION

#####How to get a return of NodeList:
Below way of querying the DOM returns NodeList and am a big fan of that way of querying the DOM for some reasons best known to me 🙂.
    document.querySelector(‘elementOrAttributeAsIdentifier’)


#####How to get a return of HTMLCollection:

Below way of querying the DOM returns HTMLCollection.
    document.getElementById(‘id’)


___
###9. childNodes vs children property

####childNodes
As I mentioned earlier, there is a logic you can use to get a live collection of Nodes and with **childNodes** property, you get all the direct Nodes present inside an element including text, comment, nested element and so on.

    document.querySelector(‘div’).childNodes;

####children
While writing this article, I decided to touch this property so you can understand HTMLCollection more.

**children** is a Node property that returns only items whose NODE_NAME is ElEMENT_NODE(That is, they return only valid HTML elements and not comment, text, or any other content). This means that if you have text inside a **<p>** and you try to retrieve the children of that **p tag(<p>)**, it will return 0 lengths for you because **paragraph text** is a TEXT_NODE and NOT an ELEMENT_NODE but reverse is the case when you try to get childNodes of **p tag(<p>)**(childNodes will return all the nested content of a parent Node and classify them into different NODE_NAME and TYPE). 


___
###10. IN-DEPTH VIDEO EXPLANATION OF THE DOM
**Link to clone the project**:[Click me to clone the project🙂 ](https://github.com/Emmybest1/DOM-tutorial-app)

####VIDEO ONE:
**Detail about this video**: In this session, we will be going through the application that we will be using for this tutorial.

<a href="https://youtu.be/vZUEm7uxuNo">
<img src="https://i.ibb.co/0cXQkdM/You-Tube-Update-Terms-of-Service.jpg" alt="DOM-Tutorial 1" border="0">
</a>



####VIDEO TWO:
**Detail about this video**: In this session, we are going to learn about the DOM and how it's been constructed.
**Link to MDN to read more about the DOM Interface**:https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model

<a href="https://youtu.be/JA3jHQrY2D4">
<img src="https://i.ibb.co/0cXQkdM/You-Tube-Update-Terms-of-Service.jpg" alt="DOM-Tutorial 1" border="0">
</a>


__
####VIDEO THREE:
**Detail about this video**: In this session, we will be looking into how the DOM Node is been created out of our HTML page.

<a href="https://youtu.be/Ra5I29nBlUk">
<img src="https://i.ibb.co/0cXQkdM/You-Tube-Update-Terms-of-Service.jpg" alt="DOM-Tutorial 1" border="0">
</a>


__
####VIDEO FOUR:
**Detail about this video**: In this session, we will be looking into a few Node properties and methods. i.e the possible property and method a Node can access.

**Note**: I did mention the NodeList having a forEach proto, this **NodeList** is not a **Node** but rather a **childNodes proto** that keeps the childNodes of a **parent Node** ** all together**(in a container that looks like an array but not an array).

<a href="https://youtu.be/DG07QdMZO9U">
<img src="https://i.ibb.co/0cXQkdM/You-Tube-Update-Terms-of-Service.jpg" alt="DOM-Tutorial 1" border="0">
</a>


__
####VIDEO FIVE:
**Detail about this video**: In this session, we will be looking into the difference between a **NodeList** and an **HTMLCollection**

**Note**: querySelector and getElementByTagName,getElementById... these are simply ways to query the DOM, and it's so powerful that right from your document, the DOM figures out where to find the element or Node you are querying.

<a href="https://youtu.be/DdENp97M9E0">
<img src="https://i.ibb.co/0cXQkdM/You-Tube-Update-Terms-of-Service.jpg" alt="DOM-Tutorial 1" border="0">
</a>


__
####VIDEO SIX:
**Detail about this video**: In this session, we will be learning how to convert a NodeList and HTMLCollection into Array.

**NOTE**: In other to access the class attribute of a Node right from your javascript code, kindly use the props name of a Node called **className** because **class** means a different thing in javascript which is relative to OOP.

<a href="https://youtu.be/VB7i5NnT0vM">
<img src="https://i.ibb.co/0cXQkdM/You-Tube-Update-Terms-of-Service.jpg" alt="DOM-Tutorial 1" border="0">
</a>


*In the below video, we fixed the condition error which was as a result of differences between class and className in Javascript/DOM*

<a href="https://youtu.be/iKxRx1cXf14">
<img src="https://i.ibb.co/0cXQkdM/You-Tube-Update-Terms-of-Service.jpg" alt="DOM-Tutorial 1" border="0">
</a>

__
###11. Bonus (onload, DOMContentLoaded, defer)
####defer: are used in script tags which tells the browser to do the following things:
i. this script which is present inside this HTML file belongs to this HTML file or page therefore, load the script into the background of this HTML page.

ii. run and execute this defer script ones the **DOM is created and ready**, but do that before the execution of the **DOMContentLoaded** event!.
So, does are the things the defer attribute does in script tags.

__
####DOMContentLoaded: 
This is an event that fires ones the initial or skeletical html has been loaded before the stylesheets,resources(image,video,animations...),subframes(subframes is like when you use the <iframe src="https://youmustknowjs.com"> </iframe> tag to load external web page to another web page) finish loading.

####onload
this is an event that fires when the HTML and all its resources(stylesheet, assets....) have finished loading. 
[Click Me to read more about javascript events](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event)

##CONCLUSION
BRAVO YOU MADE IT TO THE END 🙌 🥂, I will be releasing the next tutorial on **Shadow DOM** and how to create ours so stay tuned.