coderMe
coderMe

Reputation: 2169

Append NodeList to HTML element

I have the following string:

var songlist = '<div class="list-item" id="57902ccae53fa51716424034"><div class="media"><img src="{imgsrc}" alt="Mama Tried" /></div><h4 class="title">Mama Tried</h4><div class="song-controls"><button class="song play"><span class="fa fa-play"></button></div></div><div class="list-item" id="57902cddae7b54e264fcc6e4"><div class="media"><img src="{imgsrc}" alt="Blue Eyes Crying In the Rain" /></div><h4 class="title">Blue Eyes Crying In the Rain</h4><div class="song-controls"><button class="song play"><span class="fa fa-play"></button></div></div>';

Which I am converting to a NodeList through this custom function:

var toDom = function(str) {
  var tmp = document.createElement("div");
  tmp.innerHTML = str;
  return tmp.childNodes;
};

console.log(toDom(songlist)) outputs NodeList [ <div#57902ccae53fa51716424034.list-item>, <div#57902cddae7b54e264fcc6e4.list-item> ], which you can browse through the devtools.

When I try to append the collection to a node...

document.getElementById("app-data").appendChild(toDom(songlist));

I get TypeError: Argument 1 of Node.appendChild does not implement interface Node. Which is odd, because the docs for Node.appendChild() say that argument 1 must be of type Node.

So, what type of element does Node.appendChild() expect? I've also tried HTMLCollection.

See JSFiddle.

Upvotes: 14

Views: 19845

Answers (3)

defend orca
defend orca

Reputation: 743

now, you can use element.append() and element.childNodes straightly. just like:

var container = document.getElementById("app-data");
var childNodes = toDom(songlist);
container.append(...childNodes)
function toDom(str) {
  var tmp = document.createElement("div");
  tmp.innerHTML = str;
  return tmp.childNodes;
};

Upvotes: 10

Jeff Walters
Jeff Walters

Reputation: 4433

In this case I would use the <template> tag. It inherits from Element and it has a nifty HTMLTemplateElement.content property that gives you a DocumentFragment which can be appended directly into another element.

var container = document.getElementById("app-data");
var childNodesFragment = stringToFragment(songlist);
container.appendChild(childNodesFragment);

function stringToFragment(string) {
    var renderer = document.createElement('template');
    renderer.innerHTML = string;
    return renderer.content;
};

Upvotes: 0

dfsq
dfsq

Reputation: 193271

The problem is that Node.childNodes is a NodeList. So when you try to append it, it fails of course, because NodeList is not the same as Node. You could append child nodes one by one in loop:

var container = document.getElementById("app-data");
var childNodes = toDom(songlist);

for (var i = 0; i < childNodes.length; i++) {
    container.appendChild(childNodes[i])
}

Upvotes: 14

Related Questions