Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

175
Vistas
atributoChangedCallback() siempre se llama dos veces y termina con múltiples detectores de eventos

Jugando con elementos personalizados, estoy tratando de activar un evento de clic según el valor del atributo del elemento personalizado. Pero usando el attributeChangedCallback() (junto con el método connectedCallback() ) estoy terminando con múltiples detectores de eventos.

 class HelloWorld extends HTMLElement { static get observedAttributes() { return ['attribute1', 'attribute2']; } get attribute1() { return this.getAttribute('attribute1'); } set attribute1(val) { if (val) { this.setAttribute('attribute1', val); } else { this.removeAttribute('attribute1'); } } get attribute2() { return this.getAttribute('attribute2'); } set attribute2(val) { if (val) { this.setAttribute('attribute2', val); } else { this.removeAttribute('attribute2'); } } constructor() { super(); } connectedCallback() { this.textContent = 'Hello World'; update(this); } attributeChangedCallback(name, oldValue, newValue) { update(this); } } customElements.define('hello-world', HelloWorld); function update(el) { if (el.attribute1 === 'foo') { el.addEventListener('click', e => { el.textContent = (el.textContent.indexOf(' (') != -1 ? el.textContent.substring(0, el.textContent.indexOf(' (')) : el.textContent) + ' (clicked ' + (el.textContent.match(/\d+/) ? parseInt(el.textContent.match(/-?\d+/)[0]) + 1 : 1) + ' times)'; }); } else if (el.attribute1 === 'bar') { el.addEventListener('click', e => { el.textContent = (el.textContent.indexOf(' (') != -1 ? el.textContent.substring(0, el.textContent.indexOf(' (')) : el.textContent) + ' (clicked ' + (el.textContent.match(/\d+/) ? parseInt(el.textContent.match(/-?\d+/)[0]) - 1 : 1) + ' times)'; }); } }
 hello-world { cursor: pointer; }
 <hello-world attribute1="foo" attribute2=""></hello-world>

¿Por qué el método attributeChangedCallback() siempre se llama dos veces y, por lo tanto, agrega dos detectores de eventos? ¿Cómo evitar esto? ¿Cuál sería la mejor práctica?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Se llama attributeChangedCallback , por lo que se activa en cada cambio de atributo, incluido init cuando el elemento se agrega al DOM.

Adjunte oyentes en la devolución de llamada connectedCallback , pero eso puede ejecutarse nuevamente si mueve el elemento en el DOM, por lo que debe eliminarlos en la devolución de disconnectedCallback .

Más fácil podría ser usar un EventHandler en línea , solo puede haber uno en un elemento.

 customElements.define('hello-world', class extends HTMLElement { static get observedAttributes() { return ['attribute1', 'attribute2']; } get attribute1() { return this.getAttribute('attribute1'); } set attribute1(val) { this.toggleAttribute('attribute1', val); } get attribute2() { return this.getAttribute('attribute2'); } set attribute2(val) { this.toggleAttribute('attribute2', val); } connectedCallback() { this.count = 0; this.innerHTML = `Hello World clicked: <span>${this.count}</span> times`; this.onclick = (evt) => { this.count++; this.querySelector("span").innerHTML = this.count; } } attributeChangedCallback(name, oldValue, newValue) { console.log("attributeChangedCallback", name, oldValue, newValue); } });
 hello-world { cursor: pointer; }
 <hello-world attribute1="foo" attribute2=""></hello-world>

 constructor() { super() }

no es necesario, un constructor no existente ejecutará el constructor desde su padre... que es lo que hace super() .

Si desea evitar múltiples oyentes, puede probar un método:

 addListeners(){ .. add your listeners this.addListeners = () => {}; // overload; Don't run its original code again }

También tenga en cuenta que los oyentes que agrega en el elemento (o su contenido) se recolectan / eliminan automáticamente cuando el elemento se elimina del DOM.
Cualquier oyente que agregue en otros elementos DOM (por ejemplo, documento) debe eliminarse en la devolución de disconnectedCallback

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda