admin管理员组

文章数量:1199822

If we define a property like this on a color-span custom element:

  static get observedAttributes() {
    return ['bgc'];
  }

And get a reference to an instance like this while also changing the bgc property, should that cause the attributeChangedCallback to fire?

const colorSpan = document.querySelector('color-span');
console.log(colorSpan);
colorSpan.bgc = 'BLUE';

I tried it in this demo, and it does not fire, so I just wanted to confirm my understanding that the attributeChangedCallback will only fire when an attribute is set declaratively like this:

<color-span bgc="RED">Hello From Color Span</color-span>

If we define a property like this on a color-span custom element:

  static get observedAttributes() {
    return ['bgc'];
  }

And get a reference to an instance like this while also changing the bgc property, should that cause the attributeChangedCallback to fire?

const colorSpan = document.querySelector('color-span');
console.log(colorSpan);
colorSpan.bgc = 'BLUE';

I tried it in this demo, and it does not fire, so I just wanted to confirm my understanding that the attributeChangedCallback will only fire when an attribute is set declaratively like this:

<color-span bgc="RED">Hello From Color Span</color-span>

Share Improve this question asked Jan 21 at 20:13 OleOle 46.9k68 gold badges237 silver badges441 bronze badges 1
  • Please post a minimal reproducible example here – mplungjan Commented Jan 21 at 20:20
Add a comment  | 

2 Answers 2

Reset to default 1

colorSpan.bgc = 'BLUE'; will set the property, not the attribute. You can set the attribute programmatically using:

colorSpan.setAttribute('bgc', 'BLUE');

This will trigger the callback. However if you want to sync the property and the attribute you will have to implement that yourself.

class ColorSpanComponent extends HTMLElement {

  static observedAttributes = ['bgc'];
  
  constructor() {
    super();
    this._container = document.createElement('span');
    this._container.append(document.createElement('slot'));
    const shadowRoot = this.attachShadow({mode: 'closed'});
    shadowRoot.append(this._container);
  }
  
  attributeChangedCallback(name, oldValue, newValue) {
    switch (name) {
      case 'bgc': 
        this._container.style.backgroundColor = newValue;  
    }
  }
  
  get bgc() {
    return this._container.style.backgroundColor;
  }
  
  set bgc(value) {
    if (this._container.style.backgroundColor !== value) {
      this._container.style.backgroundColor = value;
      this.setAttribute('bgc', value);
    }
  }
}

customElements.define('color-span', ColorSpanComponent);

const colorSpan = document.querySelector('color-span');
// log initial state
console.log(colorSpan.bgc, colorSpan.getAttribute('bgc'));
// change attribute and log
colorSpan.setAttribute('bgc', 'red');
console.log(colorSpan.bgc, colorSpan.getAttribute('bgc'));
// change property and log
colorSpan.bgc = 'blue';
console.log(colorSpan.bgc, colorSpan.getAttribute('bgc'));
<color-span bgc="green">TEST</color-span>

It is not a property, it is an attribute, and yes set as observedAttribute they fire the attributeChangedCallback, both on instantiation of the Web Component (if the attribute is declared on the Web Component and the DOM parses) and whenever the attribute is set on the Web Component

本文标签: javascriptDoes attributeChangedCallback fire when a property is set programmaticallyStack Overflow