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

问题描述 投票:0回答:2

我有一个自定义元素

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
,其中包含我的复选框,并且应该对“check”事件做出反应。 我在
my-checkreport

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

但是,这个事件监听器永远不会触发,似乎永远不会“听到”在

my-checkbox
组件中调度的“check”事件。 我尝试在构造函数中添加此侦听器,结果相同。

有什么想法我做错了吗?

背景:我这样做是为了使这些元素可组合。 我还读到开发 Web 组件的最佳实践是“使用自定义事件从组件传递信息......”

javascript dom web-component shadow-dom custom-element
2个回答
38
投票

对于最终来到这里的其他人来说,您正在寻找摆脱影子根“监狱”的具体财产是

composed

所以:

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

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

更多信息在这里:

composed
财产


28
投票

如果您的复合元素

<my-checkreport>
使用 Shadow DOM 嵌入其内容(
<my-checkbox>
、标签、样式...),则从内部元素(此处为
<my-checkbox>
)分派的事件将在(容器的)Shadow 内触发DOM。

因此,您应该将事件侦听器添加到复合自定义元素 (

this.shadowRoot
) 的 Shadow DOM 根,而不是元素 (
this
) 本身。在
<my-checkreport>

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

有关 Shadow DOM 的更多信息:

© www.soinside.com 2019 - 2024. All rights reserved.