在Web组件上侦听全局事件

时间:2018-06-03 01:21:09

标签: javascript-events web-component custom-events

我有一个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组件上未听到该事件。我认为这可能与事件捕获阶段有关(并且可能在我的自定义事件选项对象中添加另一个标志。

我还在学习Web Components的细节,并没有弄清楚这篇文章。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

您正在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上收听该活动。