如何监听自定义事件定义的 Web 组件

How to listen for custom events defined web component

我有一个自定义元素 my-checkbox,它包含一个复选框、标签、样式等。当该复选框被切换时,我在我的构造函数中定义一个 CustomEvent 命名检查,如下所示:

constructor(){
   super();
   this._shadowRoot = this.attachShadow({mode: 'open'});
   this.checkEvent = new CustomEvent("check", {
     bubbles: true,
     cancelable: false,
   });
 }

我在复选框被切换时发送该事件:

toggleCheckbox(){
  this.dispatchEvent(this.checkEvent);
  console.log(this.checkEvent);
  ...
}

我推断正在调度此事件,因为 console.log 的内容显示了 CustomEvent

的签名

我有另一个自定义元素 my-checkreport,它包含 my-checkbox 并且应该对 "check" 事件做出反应。我在 my-checkreport

的连接回调中定义了一个事件监听器
connectedCallback(){
  ...
  this.addEventListener("check", function (e) {
        console.log('listend to check event');
        console.log(e);
    });
 }

但是,此 eventListener 永远不会触发,似乎永远不会 'hear' 在 my-checkbox 组件中调度的 "check" 事件。我尝试在构造函数中添加此侦听器,结果相同。

知道我做错了什么吗?

背景:我这样做是为了使这些元素可组合。我还读过开发 Web 组件的最佳实践是 "Use custom events to pass information out of components..."

如果您的复合元素 <my-checkreport> 使用影子 DOM 来嵌入其内容(<my-checkbox>、标签、样式...),则从内部元素(此处 <my-checkbox>) 将在(容器的)影子 DOM.

内发射

因此,您应该将事件侦听器添加到复合自定义元素 (this.shadowRoot) 的 Shadow DOM 根而不是元素 (this) 本身。在 <my-checkreport>:

connectedCallback(){
  ...
  this.shadowRoot.addEventListener("check", function (e) {
        console.log('listend to check event');
        console.log(e);
    });
 }

有关阴影的更多信息DOM:

对于最终来到这里的其他人,您正在寻找突破影子根 'jail' 的特定 属性 是 "composed"。

所以:

this.checkEvent = new CustomEvent("check", {
  bubbles: true,
  cancelable: false,
  composed: true
});

如果您愿意,您还可以添加另一个 属性、"detail",它将携带有关事件的自定义数据。

更多信息在这里:composed property