在构造函数中定义自定义元素的生命周期回调

Defining the custom-element's lifecycle callbacks inside of the constructor

以下定义、创建并最终将我的 "autonomous custom element" 的实例插入到容器中:

class MyCustomElement extends HTMLElement {
  static get elementName() {
    return 'my-custom-element';
  }

  constructor() {
    const self = super();
    let _myPrivateData = 'privateValue';

    // the following does not cause the callback to be invoked at all!
    MyCustomElement.prototype.connectedCallback = function() {
      console.log('connected!');
    };

    return self;
  }

  //// this would've got invoked anyways, but there's no access to the `_myPrivateData`
  // connectedCallback() {
  //     console.log('connected!');
  // }
}

let myCustomElementName = MyCustomElement.elementName;
customElements.define(myCustomElementName, MyCustomElement);

let myCustomElement = document.createElement(myCustomElementName);
let container = document.getElementById('container');
container.appendChild(myCustomElement);
<div id="container"></div>

我已经在 "constructor" 内部定义了 connectedCallback 以访问 _myPrivateData,但是回调根本没有被调用!在 "class body" 之后立即拥有相同的代码摘录确实会导致以无法访问 _myPrivateData.

为代价调用回调

这是为什么?我应如何处理该问题才能访问 _myPrivateData(保留其 "private" 性质)并使回调调用正常工作?

由于自定义元素的实现,您必须在使用 customElements.define() 定义元素之前定义所有回调。这些回调是只读的。

要处理私有值,您可以定义自己的自定义回调,该回调将由标准 connectedCallback() 方法调用。

参见下面的示例:

class MyCustomElement extends HTMLElement {
  constructor() {
    super()
    let _myPrivateData = 'privateValue'

    // the following does not cause the callback to be invoked at all!
    this.connectedCallback = function() {
      console.log('connected! : ' + _myPrivateData )
    }
  }

  connectedCallback() {
      this.connectedCallback()
  }
}

customElements.define('my-custom-element', MyCustomElement)
<my-custom-element></my-custom-element>

更新

有效的生命周期回调实际上是只读/冻结。一旦定义了自定义元素,您就无法修改它们。

请注意,当您调用 customElements.define() 时,生命周期回调会从具有相同名称的 class 回调条目复制到自定义元素注册表,或设置为 void()如果回调名称不存在。

创建自定义元素的实例时,调用的是回调副本,而不是回调 class prototype 方法。您无法访问并因此无法修改这些副本。

您仍然可以修改 class 回调(prototype 条目),但这不会影响自定义元素的生命周期。

将强制所有相同自定义元素实例的生命周期的一致性。