监听 Web 组件上的全局事件

Listen for global events on a Web Component

我有一个 main.js 调用 API 并接收响应对象。响应后,我想触发我的自定义 Web 组件正在侦听的事件。

makeRequest(request).then((response) => { // NOTE: the API in question returns a Promise, thus using 'then()'
   dispatchCustomEvent(response);
});

let dispatchCustomEvent = (response) => {
    console.log('dispatchCustomEvent called', response);
    let myCustomEvent = new CustomEvent('package-ready',
        {
            bubbles: true,
            composed: true,
            detail: response
        }
    );
    return document.dispatchEvent(myCustomEvent);
}

此事件在主文档中有效。我已将一个侦听器附加到主文档以进行测试 ,但在我的自定义组件上听不到它

window.customElements.define('app-list',

    class AppList extends HTMLElement {

        constructor() {
            super();

            let shadowRoot = this.attachShadow({mode: 'open'});

            this.addEventListener('package-ready', e => console.log('package-ready heard on app-list', e.detail));
            shadowRoot.addEventListener('package-ready', e => console.log('package-ready heard on app-list Shadow Root', e.detail));
        }
}

正如您从上面看到的,我已经将一个侦听器附加到组件(使用 this)及其影子根(用于测试目的)。

在定义的网络组件上没有听到该事件。我认为这可能与事件捕获阶段有关(并且可能向我的自定义事件选项对象添加另一个标志。

我仍在学习 Web Components 的来龙去脉,还没有搞清楚这一部分。如有任何帮助,我们将不胜感激!

您正在 document 调度事件。事件永远不会到达组件,因为事件不会发送到页面上的每个元素。

在捕获阶段,事件从 document 向下移动到派发它的事件,然后冒泡阶段沿着树的另一个方向移动,从派发它的元素返回到 document.

要么您的组件需要将其事件侦听器添加到 document,要么您的代码需要更改为如下内容:

makeRequest(request).then((response) => { // NOTE: the API in question returns a Promise, thus using 'then()'
   dispatchCustomEvent(response);
});

let dispatchCustomEvent = (response) => {
    console.log('dispatchCustomEvent called', response);
    let myCustomEvent = new CustomEvent('package-ready',
        {
            bubbles: true,
            composed: true,
            detail: response
        }
    );
    document.querySelectorAll('app-list').forEach(
      el => {
        return el.dispatchEvent(myCustomEvent);
      }
    );
}

但我真的不建议这样做。相反,如果事件将在 document 上发送,那么您应该在 document.

上监听它