在JavaScript中的匿名函数removeEventListener

我有一个对象,它有方法。 这些方法被放入匿名函数中的对象中。 它看起来像这样:

var t = {}; window.document.addEventListener("keydown", function(e) { t.scroll = function(x, y) { window.scrollBy(x, y); }; t.scrollTo = function(x, y) { window.scrollTo(x, y); }; }); 

(有更多的代码,但这足以显示问题)

现在我想在某些情况下停止事件监听器。 因此,我试图做一个removeEventListener,但我不知道如何做到这一点。 我已经阅读过其他问题,无法在匿名函数上调用removeEventListener,但是在这种情况下也是这样吗?

我有一个匿名函数创build的方法,因此我认为这是可能的。 看起来像这样:

 t.disable = function() { window.document.removeEventListener("keydown", this, false); } 

为什么我不能这样做?

有没有其他(好)的方法来做到这一点?

奖金信息; 这只需要在Safari中工作,因此缺less即支持。

我相信这是一个匿名函数的重点,它缺less一个名称或一个方法来引用它。

如果我是你,我只是创build一个命名的函数,或者把它放在一个variables,所以你有一个参考。

 var t = {}; var handler = function(e) { t.scroll = function(x, y) { window.scrollBy(x, y); }; t.scrollTo = function(x, y) { window.scrollTo(x, y); }; }; window.document.addEventListener("keydown", handler); 

你可以通过删除它

 window.document.removeEventListener("keydown", handler); 

如果你在实际的函数中,你可以使用arguments.callee作为函数的参考。 如下所示:

 button.addEventListener('click', function() { ///this will execute only once alert('only once!'); this.removeEventListener('click', arguments.callee); }); 

编辑:这将无法正常工作,如果你在严格模式( "use strict";

Otto Nascarella在严格模式下的解决scheme是:

 button.addEventListener('click', function handler() { ///this will execute only once alert('only once!'); this.removeEventListener('click', handler); }); 
 window.document.removeEventListener("keydown", getEventListeners(window.document.keydown[0].listener)); 

可能是几个匿名函数,keydown [1]

一个不那么匿名的选项

 element.funky = function() { console.log("Click!"); }; element.funky.type = "click"; element.funky.capt = false; element.addEventListener(element.funky.type, element.funky, element.funky.capt); // blah blah blah element.removeEventListener(element.funky.type, element.funky, element.funky.capt); 

既然收到了安迪的反馈很正确,但是和许多例子一样,我希望展示这个概念的上下文扩展 ),下面是一个不那么复杂的说明

 <script id="konami" type="text/javascript" async> var konami = { ptrn: "38,38,40,40,37,39,37,39,66,65", kl: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }; document.body.addEventListener( "keyup", function knm ( evt ) { konami.kl = konami.kl.slice( -9 ); konami.kl.push( evt.keyCode ); if ( konami.ptrn === konami.kl.join() ) { evt.target.removeEventListener( "keyup", knm, false ); /* Although at this point we wish to remove a listener we could easily have had multiple "keyup" listeners each triggering different functions, so we MUST say which function we no longer wish to trigger rather than which listener we wish to remove. Normal scoping will apply to where we can mention this function and thus, where we can remove the listener set to trigger it. */ document.body.classList.add( "konami" ); } }, false ); document.body.removeChild( document.getElementById( "konami" ) ); </script> 

这允许一个有效的匿名函数结构,避免使用实际上弃用的被调用者 ,并且允许容易的移除。

顺便说一句 :设置监听器后立即删除脚本元素是一个可爱的技巧隐藏代码人们宁愿不是明显的撬眼睛( 会破坏的惊喜 😉

所以方法( 更简单的 )是:

 element.addEventListener( action, function name () { doSomething(); element.removeEventListener( action, name, capture ); }, capture ); 

JavaScript :addEventListener 方法在其被调用的EventTarget(元素|文档|窗口)上注册指定的侦听器。

事件目标。 addEventListener ( event_type ,handler_function, Bubbling | Capturing );

鼠标,键盘事件 WebConsole中的示例testing:

 var keyboard = function(e) { console.log('Key_Down Code : ' + e.keyCode); }; var mouseSimple = function(e) { var element = e.srcElement || e.target; var tagName = element.tagName || element.relatedTarget; console.log('Mouse Over TagName : ' + tagName); }; var mouseComplex = function(e) { console.log('Mouse Click Code : ' + e.button); } window.document.addEventListener('keydown', keyboard, false); window.document.addEventListener('mouseover', mouseSimple, false); window.document.addEventListener('click', mouseComplex, false); 

removeEventListener 方法将删除先前使用EventTarget.addEventListener()注册的事件侦听

 window.document.removeEventListener('keydown', keyboard, false); window.document.removeEventListener('mouseover', mouseSimple, false); window.document.removeEventListener('click', mouseComplex, false); 

我可以用吗

为了给这个更新的方法:

 //one-time fire element.addEventListener('mousedown', { handleEvent: function (evt) { element.removeEventListener(evt.type, this, false); } }, false); 

这并不理想,因为它可以消除所有的情况,但可能会满足您的需求:

 z = document.querySelector('video'); z.parentNode.replaceChild(z.cloneNode(1), z); 

克隆节点将复制其所有属性及其值,包括内部(内联)侦听器。 它不会复制使用addEventListener()添加的事件侦听器

Node.cloneNode()

 window.document.onkeydown = function(){};