Question

I am following the html5rocks shadow DOM tutorials, and I thought, "what if I could use a script to add a shadow dom to every element belonging to a class." But it hasn't been working. I have the following html:

<div class="nameTag">Bob</div>
<div class="nameTag">Jim</div>
<template id="name-tag">...</template>

and then this javascript:

<script>
   var nameTags = document.querySelectorAll('.nameTag');
   var template = document.querySelector('template#name-tag');
   for (var i = nameTags.length - 1; i >= 0; i--) {
      var shadow = nameTags[i].webkitCreateShadowRoot();
      shadow.appendChild(template.content);
      template.remove();
   };
</script>

This code only displays the template with the name Jim. Upon looking in the chrome dev tools, I see there is a shadow root at <div class="nameTag">Bob</div>, but for some reason it is empty. This pattern continues no matter how many .nameTag elements I have, with only the last tag's shadow root having any content. Is there a problem in my script?

Was it helpful?

Solution

You can certainly do this, you have a couple of problems here.

First you should do .remove() on the template outside of the loop (once you're finished with it).

Second appendChild moves that element from the template to the shadow DOM. Since you do the loop backwards it gets moved to Jim first and then is no longer available for Bob. What you need to do in cloneNode at each stage and append the clone, like this:

for (var i = nameTags.length - 1; i >= 0; i--) {
    var shadow = nameTags[i].webkitCreateShadowRoot();
    var clone = template.content.cloneNode(true);
    shadow.appendChild(clone);
};
template.remove();

Here's a working jsFiddle.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top