Wadi Diaz-wong
Wadi Diaz-wong

Reputation: 121

why is appendChild not working on <li> template tag

I have this JS and HTML content:

const parent = document.querySelector('#parent');
const choices = parent.dataset.choices.split(",")

const childTplt = document.querySelector('#children');
for (c of choices) {
  let child = childTplt.content.cloneNode(true);

  child.appendChild(document.createTextNode(c));
  parent.appendChild(child);
}
<ul id="parent" data-choices="one,two,three">
</ul>
<template id="children">
   <li> </li> 
</template>

and end up with this on my page:

<ul id="parent" data-choices="one,two,three"> 
  <li> </li> 
one
  <li> </li> 
two
  <li> </li> 
three</ul>

Why is that text content ends up as sibling of <li> and not as an actual children (inside of <li></li> ?

thanks for your input!

Upvotes: 2

Views: 470

Answers (4)

Xurshid Karimov
Xurshid Karimov

Reputation: 1

The template tag has no immediate children. If you look at the properties of the template tag via console.log , you will see the property children: show HTMLCollection. The tags that are inside the tag are stored inside the "content" property and there it shows that HMTLCollection[1] (in your case). In this collection, the <li> tag has an index of 0. I hope you understand everything else. That's all.

    const parent = document.querySelector('#parent');
    const choices = parent.dataset.choices.split(",");

    const [childTplt] = document.getElementsByTagName("template");

    for (c of choices) {
       let child = childTplt.content.children[0].cloneNode(true);  
       child.appendChild(document.createTextNode(c));
       parent.appendChild(child);
    }

Upvotes: 0

Web Ninja
Web Ninja

Reputation: 109

In the loop above, you are appending c (one, two, three), then appending a cloned version of what is inside #children.

for (c of choices) {
  let child = childTplt.content.cloneNode(true);

  child.appendChild(document.createTextNode(c)); //will append 'one'
  parent.appendChild(child); //will append <li></li>
}

You can replace it with this loop and it will do what you are aiming for:

for (c of choices) {
    let li = document.createElement('li');
    li.append(c);
    parent.append(li);
}

Upvotes: 0

Zia
Zia

Reputation: 683

This worked for me

function function1() {
  var ul = document.getElementById("list");
  var li = document.createElement("li");
  li.appendChild(document.createTextNode("Four"));
  li.setAttribute("id", "element4"); 
  ul.appendChild(li);
  alert(li.id);
}

Upvotes: 0

Pointy
Pointy

Reputation: 413826

The .content property of a template element is a document fragment; it is not the <li> element. In your case, the template is simple, so you can just reference the first child of the fragment:

  let child = childTplt.content.firstElementChild.cloneNode(true);

Upvotes: 3

Related Questions