Search code examples
javascripthtmlweb-componentcustom-element

Why is attributeChangedCallback called twice?


I'm building a simple custom element, using the custom elements polyfill. I've registered an attribute to be "watched" (using observedAttributes()), and when I change the value of this attribute, the function attributeChangedCallback is called twice.

Here is the HTML code:

<my-component id="compo" foo="bar"></my-component>

<button id="myBtn">Change attribute value</button>

Here is my component definition:

class MyComponent extends HTMLElement {
  constructor() {
    super();
  }
  
  static get observedAttributes() {
    return ['foo'];
  }
  
  attributeChangedCallback(attrName, oldVal, newVal) {
    console.log('[my component] attribute', attrName, 'changed from', oldVal, 'to', newVal);
  }
}

window.customElements.define('my-component', MyComponent);

// Change value of the component attribute
$('#myBtn').click(() => $('#compo').attr('foo', 'baz'));

On that page, when I click on the button, I have the following logs in the console.log:

[my component] attribute foo changed from bar to baz

[my component] attribute foo changed from bar to baz

Why is attributeChangedCallback called twice? How can I avoid it?

The JSFiddle of this example is here: https://jsfiddle.net/czo1355c/

Thanks.


Solution

  • Since the custom-elements.js polyfill is an alpha version and not stable yet, you should use instead the polyfill from WebReflection: