[SOLVED] why it doesn’t loop through the loop (JavaScript, Class, ShadowDOM, HTML Template tag) – Stack Overflow

Issue

This Content is from Stack Overflow. Question asked by moeyg

      class Product extends HTMLElement {
        connectedCallback() {
          let products = [
            { name: "carrot", price: "$ 6.99" },
            { name: "blueberry", price: "$ 6.99" }
          ];

          let pro = document.querySelector("#product_item").content;
          let copyHTML = document.importNode(pro, true);

          for (let product of products) {
            copyHTML.querySelector(".cerealName").textContent = product.name;
            this.attachShadow({ mode: "open" });
            this.shadowRoot.append(copyHTML.cloneNode(true));
          }
        }
      }
      customElements.define("product-item", Product);
    <main>
      <product-item></product-item>
      <product-item></product-item>
    </main>

    <template id="product_item">
      <li class="cereal">
        <p class="cerealName" style="font-size: 3rem"></p>
      </li>
    </template>

I expected the result to be a

carrot blueberry

But the result came with

carrot carrot

I can’t seem to run the loop, can you tell me why?



Solution

You only need to call attachShadow once – after that it generates an error:

Failed to execute ‘attachShadow’ on ‘Element’: Shadow root cannot be created on a host which already hosts a shadow tree.

You also only need one <product-item> element.

      class Product extends HTMLElement {
        connectedCallback() {
          let products = [
            { name: "carrot", price: "$ 6.99" },
            { name: "blueberry", price: "$ 6.99" }
          ];

          let pro = document.querySelector("#product_item").content;
          let copyHTML = document.importNode(pro, true);
          this.attachShadow({ mode: "open" });
          for (let product of products) {
            copyHTML.querySelector(".cerealName").textContent = product.name;
            this.shadowRoot.append(copyHTML.cloneNode(true));
          }
        }
      }
      customElements.define("product-item", Product);
    <main>
      <product-item></product-item>
    </main>

    <template id="product_item">
      <li class="cereal">
        <span class="cerealName" style="font-size: 1.3rem"></span>
      </li>
    </template>


This Question was asked in StackOverflow by moeyg and Answered by JMP, It is licensed under the terms of
CC BY-SA 2.5.CC BY-SA 3.0.CC BY-SA 4.0.

people found this article helpful. What about you?