Web 组件中的火灾事件

Kre*_*ist 8 javascript events web-component

我试图从网络组件中引发事件,但确实如此。

<my-component id="xyz" bez="hallo" hello="myScript()"></my-component>
<script>
    xyz.addEventListener("hello", function(event) {
        console.log(event.detail.name);
    });
</script>
Run Code Online (Sandbox Code Playgroud)

html 标签“hello”和事件监听器都不会引发该事件。

Web 组件如下所示:

var button=document.createElement("button");
button.innerHTML=cap;
button.addEventListener('click', () => {
    console.log("click");
        
    button.dispatchEvent(new CustomEvent("hello", {
        detail: { name: "John" }
    }));
});
    
shadow.appendChild(button);
Run Code Online (Sandbox Code Playgroud)

谁能帮我找出错误吗?多谢。

代码小提琴:https: //jsfiddle.net/b43uqsLp/2/

Dan*_*man 5

其他答案中缺少一些信息

  • 按钮click侦听器位于 ShadowDOM内部,因此composed没有用处
  • 默认侦听器click不会被 ShadowDOM停止
  • !!! CustomEvents 需要 composed:truebubbles:true使用“open”shadowDOM 转义自定义元素。
  • connectedCallback除非您 100% 确定这就是您想要的,否则不要在 中附加侦听器;connectedCallback当 DOM 元素在文档中移动时再次运行
  • super()返回设置“this”,并attachShadow()返回设置this.shadowRoot引用,无需使用您自己的变量。
    首先运行 super意味着在创建之前您无法访问“this”;但你可以在super() 调用之前运行任何你想要的 JS

这个 JSFiddle:https://jsfiddle.net/CustomElementsExamples/qody0u4n/

节目composedbubbles行为,有更多的听众document

  document.addEventListener("click", (evt) => log(evt, 'document'));
  document.addEventListener("MyEvent", (evt) => log(evt, 'document'));
Run Code Online (Sandbox Code Playgroud)
<my-component id=ONE></my-component>
<my-component id=TWO composed>
    <my-component id=INSIDETWO composed></my-component>
</my-component>
<my-component id=THREE composed bubbles>
    <my-component id=INSIDETHREE composed bubbles></my-component>
</my-component>
Run Code Online (Sandbox Code Playgroud)

笔记

  • 元素 ONE 或文档均未捕获任何 MyEvents

  • CustomEvent("MyEvent")仅当composed和 都bubbles设置时,文档才会收到

  • 事件composed不会在shadowRoot边界停止!它在自定义元素边界处停止。在 JSfiddle 中还有其他内容DOMlistenersmy-component演示这一点。


另请参阅:https://pm.dartus.fr/blog/a-complete-guide-on-shadow-dom-and-event-propagation/


Com*_*ide 4

问题的发生是由于Shadow DOM(尝试检查你的组件,你就会明白我的意思): 在此输入图像描述

好消息,修复起来非常简单 - 只需通过composed: trueCustomEvent 选项中的属性将事件通过影子 DOM 传播到常规 DOM 中即可:

button.dispatchEvent(new CustomEvent("hello", {
    detail: { name: "John" },
    composed: true // Like this
}));
Run Code Online (Sandbox Code Playgroud)

这是JSFIDDLE