Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

109
Views
por qué no recorre el ciclo (JavaScript, Class, ShadowDOM, etiqueta de plantilla HTML)

 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>

Esperaba que el resultado fuera un

arándano zanahoria

Pero el resultado vino con

zanahoria zanahoria

Parece que no puedo ejecutar el bucle, ¿puedes decirme por qué?

almost 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Solo necesita llamar a attachShadow una vez; después de eso, genera un error:

No se pudo ejecutar 'attachShadow' en 'Elemento': la raíz de la sombra no se puede crear en un host que ya alberga un árbol de sombra.

También solo necesita un <product-item> .

 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>

almost 4 years ago · Santiago Trujillo Report

0

Y también está clonando <template> dos veces con importNode y cloneNode

cloneNode es todo lo que necesita, importNode es para importar desde otros documentos.

Y su componente procesó todos los products en un solo componente; mientras tiene múltiples <product-item> en hora HTML

Así que supongo que quiere hacer que <product-item> muestre un producto

Lo reescribí un poco para (con suerte) dejar que el código se explique solo:

Nota: el uso de shadowDOM probablemente sea excesivo, ahora bloquea el estilo del contenido.
Se elimina fácilmente eliminando 1 .attachShadow(...) y 3 referencias .shadowRoot .

 customElements.define("product-item", class extends HTMLElement {
 connectedCallback() {
 let products = [{ name: "carrot", price: "6.99" },
 { name: "blueberry", price: "6.99" }];

 let template = document.getElementById(this.nodeName).content;
 this.attachShadow({mode:"open"}).append(template.cloneNode(true));
 
 let product = products[this.getAttribute("nr")-1]; // UX starts at 1
 
 if (product) {
 this.shadowRoot.querySelector("b").textContent = product.name;
 this.shadowRoot.querySelector("span").innerHTML = ` US$ ${product.price}`;
 } else {
 this.shadowRoot.innerHTML = `No product`
 }
 }
});
 <ul>
 <product-item nr=1></product-item>
 <product-item nr=2></product-item>
 <product-item nr=3></product-item>
</ul>

<template id="PRODUCT-ITEM">
 <li class="product">
 <b>NAME</b><span>PRICE</span>
 </li>
</template>

<style>
 body {
 color: red; /* "Inheritable" CSS styles not blocked! */
 }
 .product { /* blocked by shadowDOM */
 color:green; 
 }
</style>

Si desea que un <my-products> cree todo el HTML de una sola vez; innerHTML es más corto y más rápido

 customElements.define("my-products", class extends HTMLElement {
 connectedCallback() {
 let products = [{ name: "carrot", price: "$ 6.99" },
 { name: "blueberry", price: "$ 6.99" }];

 this
 //.attachShadow({mode:"open"})
 .innerHTML = products.map(product =>
 `<li class="product"><b>${product.name}</b> - ${product.price}</li>`
 ).join("");
 }
});
 <my-products></my-products>

<style>
 .product {
 color:green;
 }
</style>

almost 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!