代码之家  ›  专栏  ›  技术社区  ›  connexo

删除使用bind添加的事件侦听器(此)

  •  4
  • connexo  · 技术社区  · 5 年前

    去除 单击我绑定到的侦听器 window constructor 在下面我需要它来听 窗口

    class MyEl extends HTMLButtonElement {
      constructor() {
        super();
        this.clickCount = 0;
        window.addEventListener('click', this.clickHandler.bind(this));
      }
      
      clickHandler(e) {
        if (e.target === this) {
          this.textContent = `clicked ${++this.clickCount} times`;
          window.removeEventListener('click', this.clickHandler);
        }
      }
      
      disconnectedCallback() {
          window.removeEventListener('click', this.clickHandler);
      }
    }
    
    customElements.define('my-el', MyEl, { extends: 'button' });
    <button is="my-el" type="button">Click me</button>
    2 回复  |  直到 5 年前
        1
  •  11
  •   CertainPerformance    5 年前

    您当前的实现不可能做到这一点,因为 .bind removeEventListener 如果传递的函数相同,则删除侦听器( === addEventListener (就像 .includes .has 适用于(套):

    const fn = () => 'foo';
    console.log(fn.bind(window) === fn.bind(window));

    作为一种解决方法,您可以将绑定函数分配给实例的属性:

    class MyEl extends HTMLButtonElement {
      constructor() {
        super();
        this.clickCount = 0;
        this.boundListener = this.clickHandler.bind(this);
        window.addEventListener('click', this.boundListener);
      }
      
      clickHandler(e) {
        this.textContent = `clicked ${++this.clickCount} times`;
        window.removeEventListener('click', this.boundListener);
      }
    }
    
    customElements.define('my-el', MyEl, { extends: 'button' });
    <button is="my-el" type="button">Click me</button>
        2
  •  2
  •   kockburn    5 年前

    class MyEl extends HTMLButtonElement {
      constructor() {
        super();
        this.clickCount = 0;
        this.wrapper = e => this.clickHandler.apply(this, e);
        window.addEventListener('click', this.wrapper);
      }
      
      clickHandler(e) {
        this.textContent = `clicked ${++this.clickCount} times`;
        
        window.removeEventListener('click', this.wrapper);
      }
    }
    
    customElements.define('my-el', MyEl, { extends: 'button' });
    <button is="my-el" type="button">Click me</button>
        3
  •  1
  •   Danny '365CSI' Engelman daniel p    3 年前

    另一个 模式是保持你的听众 在…内 构造器。

    要删除事件侦听器(无论采用何种模式),可以添加“删除” 功能 创建事件侦听器的那一刻。

    从那以后 功能 listen name func 激动

    伪代码:

      listen(name , func){
        window.addEventListener(name, func);
        return () => window.removeEventListener( name , func );
      }
    
      let remove = listen( 'click' , () => alert('BOO!') );
    
      //cleanup:
      remove();
    

    运行代码段

    不断涌现的事件&阴影区

    为了节省一个小时,一旦你做更多的活动。。。

    请注意,网络组件(即CustomElements 具有 shadowDOM)需要使用 composed:true 向上的 越过它的阴影边界

        new CustomEvent("check", {
          bubbles: true,
          //cancelable: false,
          composed: true       // required to break out of shadowDOM
        });
    

    删除添加的事件侦听器

    注意:此示例不在Safari上运行,因为Apple拒绝实现扩展元素: extends HTMLButtonElement

    class MyEl extends HTMLButtonElement {
      constructor() {
        let ME = super();// super() retuns this scope; ME makes code easier to read
        let count = 0;// you do not have to stick everything on the Element
        ME.mute = ME.listen('click' , event => {
          //this function is in constructor scope, so has access to ALL its contents
          if(event.target === ME) //because ALL click events will fire!
            ME.textContent = `clicked ${ME.id} ${++count} times`;
          //if you only want to allow N clicks per button you call ME.mute() here
        });
      }
    
      listen(name , func){
        window.addEventListener( name , func );
        console.log('added' , name , this.id );
        return () => { // return a Function!
          console.log( 'removeEventListener' , name , 'from' , this.id);
          this.style.opacity=.5;
          window.removeEventListener( name , func );
        }
      }
      eol(){ // End of Life
        this.parentNode.removeChild(this);
      }
      disconnectedCallback() {
          console.log('disconnectedCallback');
          this.mute();
      }
    }
    
    customElements.define('my-el', MyEl, { extends: 'button' });
    button{
      width:12em;
    }
    <button id="One" is="my-el" type="button">Click me</button>
    <button onclick="One.mute()">Mute</button> 
    <button onclick="One.eol()">Delete</button> 
    <br>
    <button id="Two" is="my-el" type="button">Click me too</button>
    <button onclick="Two.disconnectedCallback()">Mute</button> 
    <button onclick="Two.eol()">Delete</button> 

    笔记:

    • count this.count

    • onclick=Two.disconnectedCallback() 正如示例所示,该函数不会删除元素。


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