HTML 5 introduced the <template>
element which can be used for this purpose (as now described in the WhatWG spec and MDN docs).
A <template>
element is used to declare fragments of HTML that can be utilized in scripts. The element is represented in the DOM as a HTMLTemplateElement
which has a .content
property of DocumentFragment
type, to provide access to the template's contents. This means that you can convert an HTML string to DOM elements by setting the innerHTML
of a <template>
element, and then reaching into the template
's .content
property.
Examples:
/**
* @param {String} HTML representing a single element.
* @param {Boolean} flag representing whether or not to trim input whitespace, defaults to true.
* @return {Element | HTMLCollection | null}
*/
function fromHTML(html, trim = true) {
// Process the HTML string.
html = trim ? html.trim() : html;
if (!html) return null;
// Then set up a new template element.
const template = document.createElement('template');
template.innerHTML = html;
const result = template.content.children;
// Then return either an HTMLElement or HTMLCollection,
// based on whether the input HTML had one or more roots.
if (result.length === 1) return result[0];
return result;
}
// Example 1: add a div to the page
const div = fromHTML('<div><span>nested</span> <span>stuff</span></div>');
document.body.append(div);
// Example 2: add a bunch of rows to an on-page table
const rows = fromHTML('<tr><td>foo</td></tr><tr><td>bar</td></tr>');
table.append(...rows);
// Example 3: add a single extra row to the same on-page table
const td = fromHTML('<td>baz</td>');
const row = document.createElement(`tr`);
row.append(td);
table.append(row);
table {
background: #EEE;
padding: 0.25em;
}
table td {
border: 1px solid grey;
padding: 0 0.5em;
}
<table id="table"></table>
Note that similar approaches that use a different container element such as a div
don't quite work. HTML has restrictions on what element types are allowed to exist inside which other element types; for instance, you can't put a td
as a direct child of a div
. This causes these elements to vanish if you try to set the innerHTML
of a div
to contain them. Since <template>
s have no such restrictions on their content, this shortcoming doesn't apply when using a template.
This approach was previously not always possible due to IE not having support for <template>
, but Microsoft fully killed off the Internet Explorer family of browsers in June of 2022, with Windows updates pushed out to even prevent folks from (re)installing it, so except in the rare few cases where you find yourself writing web content for dead browsers, this approach will work for you.
var nodes = document.fromString("<b>Hello</b> <br>");
– Brunella