Originally published on valentinog.com/blog
The Document Object Model is a fundamental concept at the base of everything we do inside the browser. But what exactly is that?
When we visit a web page the browser figures out how to interpret every HTML element. So that it creates a virtual representation of the HTML document, to be saved in memory. The HTML page is converted to a tree-like structure and every HTML element becomes a leaf, connected to a parent branch. Consider this simple HTML page:
<!DOCTYPE html> <html lang="en"> <head> <title>A super simple title!</title> </head> <body> <h1>A super simple web page!</h1> </body> </html>
At the top of this structure there is document, also called root element, which contains another element: html. The html element contains an head which in turns has a title. Then we have body containing an h1. Every HTML element is represented by a specific type (also called interface) and may contains text or other nested elements:
document (HTMLDocument) | | --> html (HTMLHtmlElement) | | --> head (HtmlHeadElement) | | | | --> title (HtmlTitleElement) | | --> text: "A super simple title!" | | --> body (HtmlBodyElement) | | | | --> h1 (HTMLHeadingElement) | | --> text: "A super simple web page!"
Every HTML element descends from Element but a large part of them specializes further. You can inspect the prototype for finding out to what “species” an element belongs to. The h1 element for example is an HTMLHeadingElement:
document.querySelector('h1').__proto__ // Output: HTMLHeadingElement
While HTMLHeadingElement in turn is a “descendant” of HTMLElement:
document.querySelector('h1').__proto__.__proto__ // Output: HTMLElement
At this point (especially for beginners) there could be some confusion about the difference between document and window. Let’s see how they differ!
window refers to the browser while document is the HTML page you’re currently operating, the current document. The document interface has a number of utilities, like querySelector(), a method for selecting any HTML element inside a given page:
window represents the current window’s browser and the following instruction is the same as above:
Anyhow the following syntax is more common and you’ll see it a lot more:
Every HTML element inside the DOM is also a “Node”, in fact we can inspect the node type like so:
The above code returns 1 which is the identifier for nodes of type Element. You can also inspect the node name:
The above example returns the node name in uppercase. But the most important concept to understand is that we mainly work with two types of node in the DOM:
- nodes of type Element (HTML elements)
- nodes of type Text (text nodes)
For creating new nodes of type Element the native DOM API gives us the createElement method which you’ll usually call like so:
var heading = document.createElement('h1');
And for creating text we use createTextNode:
var text = document.createTextNode('Hello world');
The two nodes can be combined together by appending the text inside a new HTML element. Last but not least we can also append the heading element to the root document:
var heading = document.createElement('h1'); var text = document.createTextNode('Hello world'); heading.appendChild(text); document.body.appendChild(heading);
When creating and manipulating elements this way we talk of "imperative DOM manipulation. Modern front-end libraries are tackling this problem by favoring a "declarative approach. Instead of commanding the browser step by step we can declare what HTML elements do we need and the library takes care of the rest.
At this point you may wonder: “could I use just jQuery? Why bothering with createElement?” I get these questions a lot.
Well, be aware that jQuery is fading away. Bootstrap 5 will remove it from the dependencies and many more are dropping it as well. There is a valid reason behind this: the native DOM API is complete and mature enough to make jQuery obsolete.
The Document Object Model is a virtual copy of the web page that the browser creates and keeps in memory. When creating, modifying, removing HTML elements we talk of "DOM Manipulation". In the past we used to rely on jQuery even for simpler tasks but today the native API is compatible and mature enough to make jQuery obsolete.
Every HTML element available in the DOM has an interface exposing a certain number of properties and methods. When in doubt about what method to use head over the excellent docs at MDN.
Most common methods for manipulating the DOM are document.createElement() for creating a new HTML element, document.createTextNode() for creating text nodes inside the DOM. Last but not least there is .appendChild() for appending your new HTML element or a text node to an existing element.
Thanks for reading and stay tuned on valentinog.com/blog!