JavaScript HTML DOM
With the HTML DOM, JavaScript can access and change all the elements of an HTML document.
The HTML DOM (Document Object Model)
When a web page is loaded, the browser creates a Document Object Model of the page.
The HTML DOM model is constructed as a tree of Objects:
The HTML DOM Tree of Objects
With the object model, JavaScript gets all the power it needs to create dynamic HTML:
- JavaScript can change all the HTML elements in the page
- JavaScript can change all the HTML attributes in the page
- JavaScript can change all the CSS styles in the page
- JavaScript can remove existing HTML elements and attributes
- JavaScript can add new HTML elements and attributes
- JavaScript can react to all existing HTML events in the page
- JavaScript can create new HTML events in the page
What You Will Learn
In the next chapters of this tutorial you will learn:
- How to change the content of HTML elements
- How to change the style (CSS) of HTML elements
- How to react to HTML DOM events
- How to add and delete HTML elements
What is the DOM?
The DOM is a W3C (World Wide Web Consortium) standard.
The DOM defines a standard for accessing documents:
«The W3C Document Object Model (DOM) is a platform and language-neutral interface that allows programs and scripts to dynamically access and update the content, structure, and style of a document.»
The W3C DOM standard is separated into 3 different parts:
- Core DOM — standard model for all document types
- XML DOM — standard model for XML documents
- HTML DOM — standard model for HTML documents
What is the HTML DOM?
The HTML DOM is a standard object model and programming interface for HTML. It defines:
- The HTML elements as objects
- The properties of all HTML elements
- The methods to access all HTML elements
- The events for all HTML elements
In other words: The HTML DOM is a standard for how to get, change, add, or delete HTML elements.
Convert String to DOM Nodes
My original post featured DOMParser , a JavaScript API for converting HTML strings into DOM nodes. While DOMParser works well in most cases, that API does have some rough edges and isn’t as performant as another API: ContextualFragment . I’ve rewritten this post to highlight ContextualFragment , but if you still care to learn about DOMParser , please see the original text at the bottom of this post.
It wasn’t too long ago that browsers were mostly stagnant when it came to implementing new APIs and features, leading to the rise of MooTools (FTW), jQuery, Dojo Toolkit, Prototype, and likewise JavaScript toolkits. Then we started doing more client side rendering and were forced to use a variety of tricks to handle templates, including massive HTML strings in our JavaScript and even abusing tags to hold our templates.
Of course after you’ve placed your content into the template, you then need to turn that string into DOM nodes, and that process had a few of its own tricks, like creating an offscreen, dummy , setting its innerHTML to the string value, grabbing the firstChild , and moving the node to its desired node. Each JavaScript toolkit would use its own strategy for converting string to DOM, highlighting the need for a standard method to accomplish this task.
Today there’s a little known (but standard) way for converting string to DOM with JavaScript: ContextualFragment .
I’ve touched on DocumentFragment to create and store DOM nodes for performance in the past, but that post illustrated element creation via document.createElement :
// Use a DocumentFragment to store and then mass inject a list of DOM nodes var frag = document.createDocumentFragment(); for(var x = 0; x
To create DOM nodes from a string of HTML we’ll use document.createRange().createContextualFragment :
let frag = document.createRange().createContextualFragment('OneTwo'); console.log(frag); /* #document-fragmentOneTwo*/
DocumentFragment objects share most of the methods that NodeList objects have, so you can use typical DOM methods like querySelector and querySelectorAll as well DOM traversal properties like firstChild with the resulting DocumentFragment :
let firstChild = frag.firstChild; let firstDiv = frag.querySelector('div'); let allDivs = frag.querySelectorAll('div');
When you’re ready to inject all of the created DOM nodes, you can simply execute:
// "placementNode" will be the parent of the nodes within the DocumentFragment placementNode.appendChild(frag);
You can also inject nodes one at a time:
placementNode.appendChild(frag.firstChild);
The document.createRange().createContextualFragment function is an awesome, sane method for converting strings to DOM nodes within JavaScript. Ditch your old shims and switch to this performant, simple API!
The Original Post: DOMParser
Today we have a standard way for converting string to DOM with JavaScript: DOMParser .
The JavaScript
All you need to do is create a DOMParser instance and use its parseFromString method:
let doc = new DOMParser().parseFromString('Hello!', 'text/html');
Returned is a document containing the nodes generated from your string. With said document you can use standard node traversal methods to retrieve the nodes we specified in our string:
let doc = new DOMParser().parseFromString('Hello!', 'text/html'); let div = doc.body.firstChild; let divs = doc.body.querySelectorAll('div');
You don’t need a single wrapping element like JSX components — you can have sibling elements:
let doc = new DOMParser().parseFromString('12', 'text/html'); let firstDiv = doc.body.firstChild; let secondDiv = firstDiv.nextSibling;
Here’s a simple wrapping function for DOMParser to retrieve the nodes:
let getNodes = str => new DOMParser().parseFromString(str, 'text/html').body.childNodes; let nodes = getNodes('12'); // [div, div]
The DOMParser object is an awesome, sane method for converting strings to DOM nodes within JavaScript. Ditch your old shims and switch to this efficient, simple API!