Cannot access attributes of a custom element from

2019-01-28 05:39发布

问题:

I'm trying to create a polyfill of sorts using the Custom Elements API for custom elements used by an in-game browser engine to display buttons and similar. However, I can't seem to access the element's attributes (eg. src, href ...) from within the constructor.

Here is an example:

class KWButton extends HTMLElement {
  constructor() {
    super();
    var attributes = this.attributes;
    var shadow = this.attachShadow({
      mode: 'open'
    });
    var img = document.createElement('img');
    img.alt = this.getAttribute('text'); // the getAttribute call returns null
    img.src = this.getAttribute('src'); // as does this one
    img.width = this.getAttribute('width'); // and this
    img.height = this.getAttribute('height'); // and this
    img.className = 'vivacity-kwbutton'; // this works fine
    shadow.appendChild(img);
    img.addEventListener('click', () => {
      window.location = this.getAttribute('href'); // this works perfectly fine
    });
  }
}
customElements.define('kw-button',
  KWButton);
<kw-button src="https://placekitten.com/g/198/39" width="198" height="39" icon_src="https://placekitten.com/g/34/32" icon_width="34" icon_height="32" href="https://placekitten.com/" text="placekiten" color="#ffffff" size="18"></kw-button>

回答1:

You cannot access the element DOM tree with querySelector() and appendChild(), and attributes with getAttribute() and setAttribute() in the constructor().

It's because at the time constructor() is called the custom element has no content yet.

You should defer that in the connectedCallback() method and it will be fine.

From the specs:

The element must not gain any attributes or children, as this violates the expectations of consumers who use the createElement or createElementNS methods.

In general, work should be deferred to connectedCallback as much as possible