'javascript: create HTMLElement from string

I want to create HTMLElement from string by javasacript, like this

element = createHTMLElement('<table class="list"><tr><td><a href="xxx">title</a></td></tr></table>')
element.addEventListener(...)
parent.appendChild(element)

and I do not want to use jQuery



Solution 1:[1]

You can create some dummy outer element:

  var div = document.createElement('DIV');

and then:

  div.innerHTML = '<table class="list"><tr><td><a href="xxx">title</a></td></tr></table>'

and then extract it from childNodes:

  div.firstChild

innerHTML is a Microsoft extension, but one universally supported on all modern browsers.

Of course you can form a simple function which does what you want from these snippets.

Solution 2:[2]

You can also append an element using the parent's innerHTML property like this:

        this.parentEl.innerHTML += `
<a-sphere 
  class="a-sim-body"
  dynamic-body 
  position="1 1 1" 
  radius="1" 
  color="blue">
</a-sphere>`

Solution 3:[3]

Use caution with the top answer as pasqal suggests.

The problem is that .firstChild might not always be what you expect. In my case, I had a single root node (so I thought), but with leading whitespace. Here's a minimal example of my failing code:

const el = document.createElement("div");
el.innerHTML = `
  <p>foo</p>
`;
el.firstChild.classList.add("foo");

The issue is that .firstChild is really a .nodeType === Node.TEXT_NODE:

const el = document.createElement("div");
el.innerHTML = `
  <p>foo</p>
`;
console.log(el.childNodes[0].nodeType === Node.TEXT_NODE);
console.log(el.childNodes[0].textContent);
console.log(el.childNodes[1].nodeType === Node.TEXT_NODE);
console.log(el.childNodes[1].textContent);

How to deal with this is use-case dependent, but you could glue together the non-text nodes with .filter or if you're sure you have one root, as was my case, you can use .find:

const el = document.createElement("div");
el.innerHTML = `
  <p>foo</p>
`;
const root = [...el.childNodes].find(e => e.nodeType !== Node.TEXT_NODE)
console.log(root);
root.classList.add("foo"); // works now

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 EFraim
Solution 2 Michael Cole
Solution 3 ggorlen