How the DOM Really Works
Let's start this new chapter or section by learning how the DOM really works behind the scenes and, more specifically, how the DOM is organized internally. This will make it easier for us to understand everything else that's going to follow in this section.
First, remember that the DOM is basically the interface between our JavaScript code and the browser.
We have written a ton of JavaScript code in this course so far, but many times completely without interacting with the browser. i.e., without using the DOM. But now, we will start working with web pages and, therefore, with the DOM. And this time, we will learn as much as possible about the DOM and how to create amazing dynamic effects.
Let's start by remembering what we already know about the DOM:
querySelector
, addEventListener
, etc.)Now, in the DOM, there are different types of nodes. For example, some nodes are HTML elements but others are just text, remember? And this is really important to understand because, all these DOM methods and properties are organized into these different types of objects. Let's now take a look at how the DOM API is organized behind the scenes.
First, every single node in the DOM tree is of the type Node
. And such as everything else in JavaScript, each node is represented in JavaScript by an object. This object gets access to special node methods and properties such as textContent
, childNodes
, parentNode
, etc.
Now that we know that there are different types of nodes, how should these be represented? Well, the above node type has a couple of child types, which are: Element
, Text
, Comment
, and Document
. So whenever there is a text inside any element, we already know that it gets it's own node of type Text
. And the same actually happens for HTML comments, because the rule says everything that in the HTML document has to go into the DOM as well.
For the element itself, there is the Element
node type. This type of node gives each HTML element access to a ton of useful methods and properties. For example, innerHTML
, children
, append
, remove
, parentElement
, etc.
So, again, each element will be represented internally as an object. Just to make this complete, the element node type has internally an HTMLElement
child type, which is the base type for all HTML elements. In other words, the HTMLElement
type has one child type for each HTML element. For example, HTMLButtonElement
, HTMLDivElement
etc. That's important because, each of these HTML elements can have different unique properties and methods. For example, the HTMLButtonElement
has a disabled
property, which is not available on the HTMLDivElement
type. Hence the DOM needs a way of storing these different attributes, and therefore, different types of HTML elements were created in the DOM API.
Just to make sure we are all on the same page, this diagram is NOT a DOM tree. It is NOT the representation of any HTML document. It is just how different types of nodes are represented behind the scenes in the DOM API.
With that being said, now comes the most important part. What makes all of this work is something called Inheritance. The question you might now ask is: what is inheritance? Well, inheritance means that all child types will also have access to the methods and properties of all their parent node types. For example, an HTMLElement
will have access to all the methods and properties of the Element
type, like innerHTML
, classList
etc. Besides that, it will also have access to all the methods and properties of the Node
type, because that is also its parent type.
We can thinks of this as if the HTMLButtonElement
for example is also an element, and also a node.
This might all seem weird at the moment, but it will make sense when we will start talking about Object Oriented Programming in JavaScript. For now what I want you to understand is that the DOM API is broken up into these different types of nodes. I also want you understand that each of these types of nodes has access to different properties and methods, and that some of them even inherit more properties and methods from their ancestors in this organization.
Let's now talk about the Document
node type. So, document
which we use all the time in DOM manipulation is in fact just another type of node. It contains important methods such as querySelector
, querySelectorAll
, and getElementById
. And on the below image note how querySelector
is available on both the Document
, and Element
types. So keep this in mind because it's going to be important later on.
We are now left with one final missing piece here 😉. Because the DOM API needs a way of allowing all the node types to listen to events. And remember, we usually listen to events by calling the addEventListener
method on an element or the document. So, why does that actually work? Well, it's because there is a special node type called EventTarget
, which is a parent to both the Node
and Window
types.
With this and thanks to inheritance, we can call addEventListener
on every single type of node in the DOM API. Because all elements as well as Document
, Window
, and even Text
and Comment
, will inherit this method. Hence, we will be able to use addEventListener
on all of them just as if it was their own method.
To be clear, we never manually create an EventTarget
object. It is just an abstract type that we do not use in practice. This happens behind the scenes to make all the functionality work as we expect it to.
To finish this lecture, in a nutshell, this is how the DOM API works, and is structured behind the scenes. If you even want to go deeper, you can check out the MDN documentation which is really fascinating.