Javascript 如何在Web组件中捕获自定义事件?

Javascript 如何在Web组件中捕获自定义事件?,javascript,dom,web-component,custom-events,native-web-component,Javascript,Dom,Web Component,Custom Events,Native Web Component,为了让Web组件彼此通信,我使用自定义事件。让我们想象一下: WebComponentA使用或包含WebComponentB,如果单击按钮,该WebComponentB将发送CustomEvent(气泡:true,组合:true)。如果WebComponentB发送此事件,WebComponentA希望执行某些操作 我应该如何在WebComponentB中发送事件 window.dispatchEvent(customEvent); 或 我应该如何在WebComponentA中捕捉事件 win

为了让Web组件彼此通信,我使用自定义事件。让我们想象一下:

WebComponentA使用或包含WebComponentB,如果单击按钮,该WebComponentB将发送CustomEvent(气泡:true,组合:true)。如果WebComponentB发送此事件,WebComponentA希望执行某些操作

我应该如何在WebComponentB中发送事件

window.dispatchEvent(customEvent);

我应该如何在WebComponentA中捕捉事件

window.addEventListener(custom-event, () => {
);

是否有任何负面影响我应该考虑使用一个或另一个?< /P>
谢谢大家!

使用
bubble:true,composited:true
在组件本身上调度事件,因此事件将冒泡到任何关注它的地方。当您想要非常明确地拥有很多可预测性和共享状态时,我的意思是这确实是一个紧密耦合,那么只需在全局
self
(即浏览器中的
窗口
)上编排事件即可。这里有一些随机的例子,我希望能有所帮助,他们所做的只是为了展示一个例子,相对来说是无用的。总的来说,这个想法是将事情松散地结合起来,当这有意义时,事件只是传递与状态更改相关的消息。组件总是相当孤立的,无论它在什么上下文中运行,都可以单独关注它对该信息的处理(准备和接收模型——这是功能模式非常适用的地方)。如果需要更多的细节或令人困惑,请随时详细说明,我们可以尝试提供帮助

还要注意的是,因为我没有设置任何shadowRoot,所以在这个示例中,composited标志一点用处都没有

大体上:

  • 全局:
    self
    (与其他上下文中的
    window
    或worker同义);在这里协调事件,目的是在许多事情上紧密耦合——当需要非常具体的协调系统时,这是迄今为止最简单的组织方案;只需在此处侦听并发送此场景的事件;在
    connectedCallback
    disconnectedCallback
    中添加和删除事件侦听器。然后使用冒泡或直接
    self在任何地方进行调度。不再需要dispatchEvent('type',{detail:…})
    和冒泡等

  • 节点:在树的任何级别,当组件具有任何状态或任何类型的事件时,处理场景并创建一条适当的消息作为
    事件。详细信息
    ,并创建一个合理的名称作为
    事件。键入
    ,然后从处理该逻辑的节点发送该消息。其他节点(对于父节点等,在其自身上)可以观察
    事件。bubble
    向上,并且当从卷影节点进行调度时,这些事件可以使用
    composed:true
    标志来允许事件在卷影根之外继续。或者,元素可以处理内部事件,并分派适合该类型的新类型的事件和负载

      <my-global>my global </my-global>
      <my-aye> aye (parent)
          <my-bee> bee (child) </my-bee>
      </my-aye>
      <my-bee> bee </my-bee>
    
    
      function eventdetails(event){
          const {type, detail} = event;
          console.log({type, detail, self:this, path: event.composedPath(), event});
      }
    
      customElements.define('my-global', class MyGlobalWatch extends HTMLElement{
          constructor(){
              super();
              this.global = this.global.bind(this);
          }
          global(event){
              eventdetails.call(this, event);
          }
          connectedCallback(){
              self.addEventListener('global', this.global);
          }
          disconnectedCallback(){
              self.removeEventListener('global', this.global);
          }
      });
      customElements.define('my-aye', class MyAye extends HTMLElement{
          constructor(){
              super();
              this.addEventListener('hi-aye', this.handle);
              this.addEventListener('hi-bee', this.handle);
          }
          handle(event){
              eventdetails.call(this, event);
              if(event.type === 'hi-bee'){
                  self.dispatchEvent(new CustomEvent('global', {detail: event.detail, cancelable: true, composed: true, bubbles: false}));
              }
          }
      });
      customElements.define('my-bee', class MyBee extends HTMLElement{
          constructor(){
              super();
              this.addEventListener('hi-aye', this.handle);
              this.addEventListener('hi-bee', this.handle);
              this.ticker = this.ticker.bind(this);
          }
          handle(event){
              eventdetails.call(this, event);
          }
          ticker(){
              // 3 events of the same type, different configuration
              this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> -composed +bubbles'}, cancelable: true, composed: false, bubbles: true}));
              this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> +composed +bubbles'}, cancelable: true, composed: true, bubbles: true}));
              this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> -composed -bubbles'}, cancelable: true, composed: false, bubbles: false}));
    
              this.dispatchEvent(new CustomEvent('hi-bee', {detail: {stuff:'things'}, cancelable: true, composed: true, bubbles: true}));
    
              this._timer = setTimeout(this.ticker, 1234);
          }
          connectedCallback(){
              this.ticker();
          }
          disconnectedCallback(){
              clearTimeout(this._timer);
          }
      });
    
    myglobal
    是(家长)
    蜜蜂(儿童)
    蜜蜂
    函数eventdetails(事件){
    const{type,detail}=事件;
    log({type,detail,self:this,path:event.composedPath(),event});
    }
    定义('my-global',类MyGlobalWatch扩展HtmleElement{
    构造函数(){
    超级();
    this.global=this.global.bind(this);
    }
    全球(活动){
    eventdetails.call(此,事件);
    }
    connectedCallback(){
    self.addEventListener('global',this.global);
    }
    disconnectedCallback(){
    self.removeEventListener('global',this.global);
    }
    });
    定义('my-aye',类MyAye扩展HtmleElement{
    构造函数(){
    超级();
    this.addEventListener('hi-aye',this.handle);
    this.addEventListener('hi-bee',this.handle);
    }
    句柄(事件){
    eventdetails.call(此,事件);
    如果(event.type==='hi-bee'){
    self.dispatchEvent(新CustomEvent('global',{detail:event.detail,cancelable:true,composited:true,bubbles:false}));
    }
    }
    });
    定义('my-bee',类MyBee扩展HtmleElement{
    构造函数(){
    超级();
    this.addEventListener('hi-aye',this.handle);
    this.addEventListener('hi-bee',this.handle);
    this.ticker=this.ticker.bind(this);
    }
    句柄(事件){
    eventdetails.call(此,事件);
    }
    股票代码(){
    //3个相同类型、不同配置的事件
    dispatchEvent(新的CustomEvent('hi-aye',{detail:{payload:'>-Composited+bubbles'},cancelable:true,Composited:false,bubbles:true}));
    dispatchEvent(新的CustomEvent('hi-aye',{detail:{payload:'>+Composited+bubbles'},可取消:true,Composited:true,bubbles:true}));
    dispatchEvent(新的CustomEvent('hi-aye',{detail:{payload:'>-composited-bubbles'},可取消:true,composited:false,bubbles:false}));
    dispatchEvent(新的CustomEvent('hi-bee',{detail:{stuff:'things'},可取消:true,组合:true,气泡:true});
    this._timer=setTimeout(this.ticker,1234);
    }
    connectedCallback(){
    this.ticker();
    }
    disconnectedCallback(){
    clearTimeout(此计时器);
    }
    });
    

这完全取决于您的代码需要实现什么,但本质上与没有Web组件的代码没有区别:
this.shadowRoot.addEventListener(custom-event, () => {
);
  <my-global>my global </my-global>
  <my-aye> aye (parent)
      <my-bee> bee (child) </my-bee>
  </my-aye>
  <my-bee> bee </my-bee>


  function eventdetails(event){
      const {type, detail} = event;
      console.log({type, detail, self:this, path: event.composedPath(), event});
  }

  customElements.define('my-global', class MyGlobalWatch extends HTMLElement{
      constructor(){
          super();
          this.global = this.global.bind(this);
      }
      global(event){
          eventdetails.call(this, event);
      }
      connectedCallback(){
          self.addEventListener('global', this.global);
      }
      disconnectedCallback(){
          self.removeEventListener('global', this.global);
      }
  });
  customElements.define('my-aye', class MyAye extends HTMLElement{
      constructor(){
          super();
          this.addEventListener('hi-aye', this.handle);
          this.addEventListener('hi-bee', this.handle);
      }
      handle(event){
          eventdetails.call(this, event);
          if(event.type === 'hi-bee'){
              self.dispatchEvent(new CustomEvent('global', {detail: event.detail, cancelable: true, composed: true, bubbles: false}));
          }
      }
  });
  customElements.define('my-bee', class MyBee extends HTMLElement{
      constructor(){
          super();
          this.addEventListener('hi-aye', this.handle);
          this.addEventListener('hi-bee', this.handle);
          this.ticker = this.ticker.bind(this);
      }
      handle(event){
          eventdetails.call(this, event);
      }
      ticker(){
          // 3 events of the same type, different configuration
          this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> -composed +bubbles'}, cancelable: true, composed: false, bubbles: true}));
          this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> +composed +bubbles'}, cancelable: true, composed: true, bubbles: true}));
          this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> -composed -bubbles'}, cancelable: true, composed: false, bubbles: false}));

          this.dispatchEvent(new CustomEvent('hi-bee', {detail: {stuff:'things'}, cancelable: true, composed: true, bubbles: true}));

          this._timer = setTimeout(this.ticker, 1234);
      }
      connectedCallback(){
          this.ticker();
      }
      disconnectedCallback(){
          clearTimeout(this._timer);
      }
  });