Convert String to DOM Nodes

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 <script> 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 <div> , 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 < 10; x++) { var li = document.createElement("li"); li.innerHTML = "List item " + x; frag.appendChild(li); }

To create DOM nodes from a string of HTML we'll use document.createRange().createContextualFragment :

let frag = document.createRange().createContextualFragment(' One Two '); console.log(frag); /* #document-fragment One Two */

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