【问题标题】:JavaScript: remove event listenerJavaScript:删除事件监听器
【发布时间】:2011-05-23 02:01:12
【问题描述】:

我正在尝试删除侦听器定义中的事件侦听器:

canvas.addEventListener('click', function(event) {
    click++;
    if(click == 50) {
        // remove this event listener here!
    }
// More code here ...

我怎么能这样做?这 = 事件...

【问题讨论】:

  • 微不足道,但对于将来的引用,if(click == 50) { 应该是 if( click === 50 )if( click >= 50 ) - 它们不会更改输出,但出于理智的原因,这些检查更有意义。
  • 好问题...如果我无法访问内容,如何删除它?我想使用其他网站的greasemonkey删除按钮的onclick弹出窗口,但除非我可以按名称引用该函数,否则我似乎找不到删除它的方法。

标签: javascript events event-handling listener


【解决方案1】:

您需要使用命名函数。

另外,click 变量需要在处理程序之外才能递增。

var click_count = 0;

function myClick(event) {
    click_count++;
    if(click_count == 50) {
       // to remove
       canvas.removeEventListener('click', myClick);
    }
}

// to add
canvas.addEventListener('click', myClick);

编辑:您可以像这样关闭click_counter 变量:

var myClick = (function( click_count ) {
    var handler = function(event) {
        click_count++;
        if(click_count == 50) {
           // to remove
           canvas.removeEventListener('click', handler);
        }
    };
    return handler;
})( 0 );

// to add
canvas.addEventListener('click', myClick);

通过这种方式,您可以跨多个元素递增计数器。


如果您不希望这样,并且希望每个人都有自己的计数器,请执行以下操作:

var myClick = function( click_count ) {
    var handler = function(event) {
        click_count++;
        if(click_count == 50) {
           // to remove
           canvas.removeEventListener('click', handler);
        }
    };
    return handler;
};

// to add
canvas.addEventListener('click', myClick( 0 ));

编辑: 我忘记命名在最后两个版本中返回的处理程序。已修复。

【讨论】:

  • +1 - 我把它做成了小提琴,但它没有用。但那是因为我需要点击五十次 :) 我真是个白痴。此处的简化示例:jsfiddle.net/karim79/aZNqA
  • @karim79:我希望我可以说我以前从未做过这样的事情。 :o) 感谢 jsFiddle。
  • +1 第三个选项对我有用。将按键事件分配给输入字段以清除验证。不错,谢谢
  • 赞成,这里的第三个选项是理解 JS 绑定/解除绑定的重要部分
  • myClick = function(event){...} 也会被视为命名函数吗?
【解决方案2】:
   canvas.addEventListener('click', function(event) {
      click++;
      if(click == 50) {
          this.removeEventListener('click',arguments.callee,false);
      }

应该这样做。

【讨论】:

  • 这太酷了!有兴趣的人在arguments.callee上的文档:developer.mozilla.org/en/JavaScript/Reference/…
  • 不幸的是,这不适用于 ECMAScript 5 (2009) 或更高版本,来自 MDN 链接:“第 5 版 ECMAScript (ES5) 禁止在严格模式下使用 arguments.callee()。避免使用 @ 987654325@ 通过给函数表达式命名或在函数必须调用自身的情况下使用函数声明。” (虽然它使用callee() 而不是callee,但它仍然被删除,嘘!)
【解决方案3】:

您可以使用命名函数表达式(在本例中,函数名为 abc),如下所示:

let click = 0;
canvas.addEventListener('click', function abc(event) {
    click++;
    if (click >= 50) {
        // remove event listener function `abc`
        canvas.removeEventListener('click', abc);
    }
    // More code here ...
}

快速而肮脏的工作示例:http://jsfiddle.net/8qvdmLz5/2/.

有关命名函数表达式的更多信息:http://kangax.github.io/nfe/

【讨论】:

    【解决方案4】:

    如果@Cyber​​nate 的解决方案不起作用,请尝试将触发器分解为它自己的函数,以便您可以引用它。

    clickHandler = function(event){
      if (click++ == 49)
        canvas.removeEventListener('click',clickHandler);
    }
    canvas.addEventListener('click',clickHandler);
    

    【讨论】:

      【解决方案5】:
      element.querySelector('.addDoor').onEvent('click', function (e) { });
      element.querySelector('.addDoor').removeListeners();
      
      
      HTMLElement.prototype.onEvent = function (eventType, callBack, useCapture) {
      this.addEventListener(eventType, callBack, useCapture);
      if (!this.myListeners) {
          this.myListeners = [];
      };
      this.myListeners.push({ eType: eventType, callBack: callBack });
      return this;
      };
      
      
      HTMLElement.prototype.removeListeners = function () {
      if (this.myListeners) {
          for (var i = 0; i < this.myListeners.length; i++) {
              this.removeEventListener(this.myListeners[i].eType, this.myListeners[i].callBack);
          };
         delete this.myListeners;
      };
      };
      

      【讨论】:

        【解决方案6】:

        如果有人使用 jquery,他可以这样做:

        var click_count = 0;
        $( "canvas" ).bind( "click", function( event ) {
            //do whatever you want
            click_count++;
            if ( click_count == 50 ) {
                //remove the event
                $( this ).unbind( event );
            }
        });
        

        希望它可以帮助某人。 请注意,@user113716 给出的答案效果很好:)

        【讨论】:

          【解决方案7】:

          我认为您可能需要提前定义处理函数,如下所示:

          var myHandler = function(event) {
              click++; 
              if(click == 50) { 
                  this.removeEventListener('click', myHandler);
              } 
          }
          canvas.addEventListener('click', myHandler);
          

          这将允许您从内部按名称删除处理程序。

          【讨论】:

            【解决方案8】:

            试试这个,它对我有用。

            <button id="btn">Click</button>
            <script>
             console.log(btn)
             let f;
             btn.addEventListener('click', f=function(event) {
             console.log('Click')
             console.log(f)
             this.removeEventListener('click',f)
             console.log('Event removed')
            })  
            </script>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-08-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多