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, then reaching into the template's .content property.
Examples:
/**
* @param {String} HTML representing a single node (which might be an Element,
a text node, or a comment).
* @return {Node}
*/
function htmlToNode(html) {
const template = document.createElement('template');
template.innerHTML = html;
const nNodes = template.content.childNodes.length;
if (nNodes !== 1) {
throw new Error(
`html parameter must represent a single node; got ${nNodes}. ` +
'Note that leading or trailing spaces around an element in your ' +
'HTML, like " <img/> ", get parsed as text nodes neighbouring ' +
'the element; call .trim() on your input to avoid this.'
);
}
return template.content.firstChild;
}
const td = htmlToNode('<td>foo</td>'),
div = htmlToNode('<div><span>nested</span> <span>stuff</span></div>');
/**
* @param {String} HTML representing any number of sibling nodes
* @return {NodeList}
*/
function htmlToNodes(html) {
const template = document.createElement('template');
template.innerHTML = html;
return template.content.childNodes;
}
const rows = htmlToNodes('<tr><td>foo</td></tr><tr><td>bar</td></tr>');
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.
Using <template>s was previously not always possible due to Internet Explorer not supporting <template>s, but IE support is almost never a consideration nowadays and Can I Use characterises <template>s as "baseline" functionality "widely available across major browsers". Except in the rare few cases where you find yourself writing web content for dead browsers, this approach will now reliably work for you.
var nodes = document.fromString("<b>Hello</b> <br>");