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

166
Views
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 answers
Answer question

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 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!