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

rak*_*tin 9 javascript dom web-component shadow-dom custom-element

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

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

切换复选框时,我会调度该事件:

toggleCheckbox(){
  this.dispatchEvent(this.checkEvent);
  console.log(this.checkEvent);
  ...
}
Run Code Online (Sandbox Code Playgroud)

我推断这个事件正在被调度,因为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);
    });
 }
Run Code Online (Sandbox Code Playgroud)

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

我有什么想法我做错了吗?

背景:我这样做是为了使这些元素可以组合.我还读过,开发Web组件的最佳实践是"使用自定义事件将信息传递出组件......"

Sup*_*arp 13

如果你的复合元素<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);
    });
 }
Run Code Online (Sandbox Code Playgroud)

有关Shadow DOM的更多信息:


Cla*_*ick 9

对于那些最终到达这里的人来说,你正在寻找的特定属性是打破阴影根"监狱"的"组成".

所以:

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

如果您愿意,还可以添加另一个属性"详细信息",该属性将包含事件的自定义数据.

更多信息在这里:组成的财产

  • 处理事件时要注意的另一件事是,这是一个愚蠢的错误,但如果您不小心,可能会咬您,请确保您使用“this”进行调度,即 this.dispatchEvent(my_custom_event); - 我无意中完成了dispatchEvent(some_event) - 代码工作正常,但你的监听器永远不会触发。这是因为如果没有“this”,您将从窗口对象分派事件,本质上是在执行 window.dispatchEvent(some_event)。 (2认同)