繁体   English   中英

JavaScript:删除事件监听器

[英]JavaScript: remove event listener

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

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

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

您需要使用命名函数。

此外, 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 ));

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

   canvas.addEventListener('click', function(event) {
      click++;
      if(click == 50) {
          this.removeEventListener('click',arguments.callee,false);
      }

应该这样做。

您可以使用命名函数表达式(在这种情况下,函数名为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/

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

clickHandler = function(event){
  if (click++ == 49)
    canvas.removeEventListener('click',clickHandler);
}
canvas.addEventListener('click',clickHandler);
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;
};
};

如果有人使用 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 给出的答案很好用:)

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

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

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

我最终为此创建了一个辅助函数:

function addDisposableEventListener({ target, eventType, eventHandler }) {
  target.addEventListener(eventType, eventHandler)
  return { dispose: () => target.removeEventListener(eventType, eventHandler) }
}

用法示例:

const button = document.querySelector('#button')
const buttonClickListener = addDisposableEventListener({
  target: button,
  eventType: 'click',
  eventHandler: event => {
    event.preventDefault()
    // ... code to handle the event
    buttonClickListener.dispose() // listener can be disposed here
  }
})

// ... more code
buttonClickListener.dispose() // listener can be disposed here

似乎没有人涵盖当前 JavaScript DOM 规范的一部分,该规范为您提供了一种无需使用removeEventListener即可删除事件侦听器的机制。 如果我们查看https://dom.spec.whatwg.org/#concept-event-listener ,我们会看到有许多属性可以传递给控制事件监听:

{
  type (a string)
  callback (null or an EventListener object)
  capture (a boolean, initially false)
  passive (a boolean, initially false)
  once (a boolean, initially false)
  signal (null or an AbortSignal object)
  removed (a boolean for bookkeeping purposes, initially false) 
}

现在,该列表中有很多有用的属性,但为了删除事件侦听器,它是我们想要使用的signal属性(在 2020 年末添加到 DOM 级别 3),因为它让我们通过调用abort()来告诉 JS 引擎删除事件侦听器,而不必费心removeEventListener

const canvasListener = (new AbortController()).signal;

canvas.addEventListener('click', function(event) {
  click++;
  if(click === 50) {
    canvasListener.abort();
  }
}, {
  signal: canvasListener 
});

(注意这里没有使用useCapture标志,因为 useCapture 标志本质上是完全没用的)

完成:JS 引擎将中止并清理我们的事件监听器。 不保留对处理函数的引用,不确保调用removeEventListener时具有与调用addEventListener完全相同的属性:我们只是取消侦听器。

实现这一点的一种方法是使用 jquery,因此您可以使用:

canvas.click(yourfunction);

然后您可以使用以下方法分离所有事件侦听器:

canvas.off();

试试这个,它对我有用。

<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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM