Note: most current browsers support HTML <template> elements, which provide a more reliable way of turning creating elements from strings. See Mark Amery's answer below for details.
For older browsers, and node/jsdom: (which doesn't yet support <template> elements at the time of writing), use the following method. It's the same thing the libraries use to do to get DOM elements from an HTML string (with some extra work for IE to work around bugs with its implementation of innerHTML):
function createElementFromHTML(htmlString) {
var div = document.createElement('div');
div.innerHTML = htmlString.trim();
// Change this to div.childNodes to support multiple top-level nodes.
return div.firstChild;
}
Note that unlike HTML templates this won't work for some elements that cannot legally be children of a <div>, such as <td>s.
If you're already using a library, I would recommend you stick to the library-approved method of creating elements from HTML strings:
- Prototype has this feature built-into its
update()method. - jQuery has it implemented in its
jQuery(html)andjQuery.parseHTMLmethods.
Note: most current browsers support HTML <template> elements, which provide a more reliable way of turning creating elements from strings. See Mark Amery's answer below for details.
For older browsers, and node/jsdom: (which doesn't yet support <template> elements at the time of writing), use the following method. It's the same thing the libraries use to do to get DOM elements from an HTML string (with some extra work for IE to work around bugs with its implementation of innerHTML):
function createElementFromHTML(htmlString) {
var div = document.createElement('div');
div.innerHTML = htmlString.trim();
// Change this to div.childNodes to support multiple top-level nodes.
return div.firstChild;
}
Note that unlike HTML templates this won't work for some elements that cannot legally be children of a <div>, such as <td>s.
If you're already using a library, I would recommend you stick to the library-approved method of creating elements from HTML strings:
- Prototype has this feature built-into its
update()method. - jQuery has it implemented in its
jQuery(html)andjQuery.parseHTMLmethods.
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.
javascript - Converting HTML string into DOM elements? - Stack Overflow
javascript - Convert a string to html tags - Salesforce Stack Exchange
Parse html elements which are contained in a string
*Best Practice* creating and writing the html with JS
You can use a DOMParser, like so:
var xmlString = "<div id='foo'><a href='#'>Link</a><span></span></div>";
var doc = new DOMParser().parseFromString(xmlString, "text/xml");
console.log(doc.firstChild.innerHTML); // => <a href="#">Link...
console.log(doc.firstChild.firstChild.innerHTML); // => Link
Run code snippetEdit code snippet Hide Results Copy to answer Expand
You typically create a temporary parent element to which you can write the innerHTML, then extract the contents:
var wrapper= document.createElement('div');
wrapper.innerHTML= '<div><a href="#"></a><span></span></div>';
var div= wrapper.firstChild;
If the element whose outer-HTML you've got is a simple <div> as here, this is easy. If it might be something else that can't go just anywhere, you might have more problems. For example if it were a <li>, you'd have to have the parent wrapper be a <ul>.
But IE can't write innerHTML on elements like <tr> so if you had a <td> you'd have to wrap the whole HTML string in <table><tbody><tr>...</tr></tbody></table>, write that to innerHTML and extricate the actual <td> you wanted from a couple of levels down.