4

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

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

html-tag "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);

谁能帮我找出错误?非常感谢。

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

4

2 回答 2

3

另一个答案中缺少一些信息

  • 按钮click监听器shadowDOM 内,所以composed没有用
  • 像这样的默认侦听click不会被 shadowDOM 停止
  • !!!CustomEvents 需要 composed:truebubbles:true使用 'open' shadowDOM 转义自定义元素。
  • connectedCallback除非您 100% 确定这是您想要的,否则不要在其中附加侦听器;当connectedCallbackDOM 元素在文档中移动时再次运行
  • super()返回设置'this',并attachShadow()返回设置this.shadowRoot引用,无需使用自己的变量。
    首先运行超级意味着您在创建之前无法访问“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'));
<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>

笔记

  • 没有一个 MyEvents 被元素 ONE 或文档捕获

  • 文档仅CustomEvent("MyEvent")在两者composedbubbles设置时接收

  • 事件composed不会在 shadowRoot 边界处停止!它在自定义元素边界处停止。在 JSfiddle 中还有其他DOMlisteners内容my-component可以证明这一点。


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

于 2021-01-26T11:16:57.290 回答
1

问题的出现是因为Shadow DOM(尝试检查您的组件,您会明白我的意思): 在此处输入图像描述

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

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

这是JSFIDDLE

于 2021-01-25T18:23:13.273 回答