removeEventListener在JavaScript中的匿名函数。

时间:2022-05-31 22:29:29

I have an object that has methods in it. These methods are put into the object inside an anonymous function. It looks like this:

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

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);
    };
});  

(there is a lot more code, but this is enough to show the problem)

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

Now I want to stop the event listener in some cases. Therefore I am trying to do a removeEventListener but I can't figure out how to do this. I have read in other questions that it is not possible to call removeEventListener on anonymous functions, but is this also the case in this situation?

现在我想在某些情况下停止事件监听器。因此,我尝试做一个removeEventListener,但是我不知道怎么做。我在其他问题中读到过,在匿名函数上调用removeEventListener是不可能的,但在这种情况下也是这样吗?

I have a method in t created inside the anonymous function and therefore I thought it was possible. Looks like this:

我在匿名函数中创建了一个t中的方法,因此我认为这是可能的。是这样的:

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

Why can't I do this?

为什么我不能这么做?

Is there any other (good) way to do this?

还有其他(好的)方法吗?

Bonus info; this only has to work in Safari, hence the missing ie support.

奖金信息;这只能在Safari中使用,因此缺少ie支持。

10 个解决方案

#1


49  

I believe that is the point of an anonymous function, it lacks a name or a way to reference it.

我认为这就是匿名函数的意义所在,它缺少一个名称或引用它的方法。

If I were you I would just create a named function, or put it in a variable so you have a reference to it.

如果我是你,我会创建一个命名函数,或者把它放到一个变量中,这样你就有了一个引用。

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

You can then remove it by

然后你可以删除它

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

#2


81  

if you are inside the actual function, you can use arguments.callee as a reference to the function. as in:

如果在实际函数中,可以使用参数。作为函数的引用。如:

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

EDIT: This will not work if you are working in strict mode ("use strict";)

编辑:如果你在严格的模式下工作(“使用严格”;)

#3


24  

A version of Otto Nascarella's solution that works in strict mode is:

奥托·纳斯卡雷拉(Otto Nascarella)在严格模式下的解决方案是:

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

#4


7  

window.document.removeEventListener("keydown", getEventListeners(window.document.keydown[0].listener));  

May be several anonymous functions, keydown[1]

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

#5


2  

A not so anonymous option

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

Since receiving feedback from Andy (quite right, but as with many examples, I wished to show a contextual expansion of the idea), here's a less complicated exposition:

由于收到了Andy的反馈(非常正确,但是和很多例子一样,我希望展示这个想法的上下文扩展),这里有一个不那么复杂的说明:

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

This allows an effectively anonymous function structure, avoids the use of the practically deprecated callee, and allows easy removal.

这允许一个有效的匿名函数结构,避免使用实际上不赞成的callee,并允许轻松删除。

Incidentally: The removal of the script element immediately after setting the listener is a cute trick for hiding code one would prefer wasn't starkly obvious to prying eyes (would spoil the surprise ;-)

顺便说一句:在设置监听器之后立即删除脚本元素是一个隐藏代码的可爱技巧,一个人可能更喜欢它,但对窥探者来说却不是那么明显(这会破坏你的惊喜;-)

So the method (more simply) is:

所以这个方法(更简单)是:

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

#6


1  

JavaScript: addEventListener method registers the specified listener on the EventTarget(Element|document|Window) it's called on.

addEventListener方法在它调用的EventTarget(元素|document|窗口)上注册指定的监听器。

EventTarget.addEventListener(event_type, handler_function, Bubbling|Capturing);

EventTarget。addEventListener(event_type handler_function,泡泡|捕获);

Mouse, Keyboard events Example test in WebConsole:

鼠标、键盘事件示例测试在WebConsole中:

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 method removes the event listener previously registered with EventTarget.addEventListener().

removeEventListener方法删除先前已注册为EventTarget.addEventListener()的事件监听器。

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

caniuse

caniuse

#7


1  

To give a more up-to-date approach to this:

就这方面提出更先进的方法:

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

#8


0  

This is not ideal as it removes all, but might work for your needs:

这并不理想,因为它消除了一切,但可能适合您的需要:

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

Cloning a node copies all of its attributes and their values, including intrinsic (in–line) listeners. It does not copy event listeners added using addEventListener()

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

Node.cloneNode()

Node.cloneNode()

#9


0  

Possibly not the best solution in terms of what you are asking. I have still not determined an efficient method for removing anonymous function declared inline with the event listener invocation.

就你的要求而言,这可能不是最好的解决方案。我还没有确定一个有效的方法来删除与事件侦听器调用内联的匿名函数。

I personally use a variable to store the <target> and declare the function outside of the event listener invocation eg:

我个人使用一个变量来存储 ,并在事件监听器调用之外声明函数:

const target = document.querySelector('<identifier>');

const目标= document.querySelector(“ <标识符> ”);

function myFunc(event) { function code; }

函数myFunc(事件){函数代码;}

target.addEventListener('click', myFunc);

目标。addEventListener(“点击”,myFunc);

Then to remove the listener:

然后移除监听器:

target.removeEventListener('click', myFunc);

目标。removeEventListener(“点击”,myFunc);

Not the top recommendation you will receive but to remove anonymous functions the only solution I have found useful is to remove then replace the HTML element. I am sure there must be a better vanilla JS method but I haven't seen it yet.

我发现唯一有用的解决方案是删除然后替换HTML元素。我相信肯定有更好的JS方法,但我还没见过。

#10


-4  

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

#1


49  

I believe that is the point of an anonymous function, it lacks a name or a way to reference it.

我认为这就是匿名函数的意义所在,它缺少一个名称或引用它的方法。

If I were you I would just create a named function, or put it in a variable so you have a reference to it.

如果我是你,我会创建一个命名函数,或者把它放到一个变量中,这样你就有了一个引用。

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

You can then remove it by

然后你可以删除它

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

#2


81  

if you are inside the actual function, you can use arguments.callee as a reference to the function. as in:

如果在实际函数中,可以使用参数。作为函数的引用。如:

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

EDIT: This will not work if you are working in strict mode ("use strict";)

编辑:如果你在严格的模式下工作(“使用严格”;)

#3


24  

A version of Otto Nascarella's solution that works in strict mode is:

奥托·纳斯卡雷拉(Otto Nascarella)在严格模式下的解决方案是:

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

#4


7  

window.document.removeEventListener("keydown", getEventListeners(window.document.keydown[0].listener));  

May be several anonymous functions, keydown[1]

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

#5


2  

A not so anonymous option

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

Since receiving feedback from Andy (quite right, but as with many examples, I wished to show a contextual expansion of the idea), here's a less complicated exposition:

由于收到了Andy的反馈(非常正确,但是和很多例子一样,我希望展示这个想法的上下文扩展),这里有一个不那么复杂的说明:

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

This allows an effectively anonymous function structure, avoids the use of the practically deprecated callee, and allows easy removal.

这允许一个有效的匿名函数结构,避免使用实际上不赞成的callee,并允许轻松删除。

Incidentally: The removal of the script element immediately after setting the listener is a cute trick for hiding code one would prefer wasn't starkly obvious to prying eyes (would spoil the surprise ;-)

顺便说一句:在设置监听器之后立即删除脚本元素是一个隐藏代码的可爱技巧,一个人可能更喜欢它,但对窥探者来说却不是那么明显(这会破坏你的惊喜;-)

So the method (more simply) is:

所以这个方法(更简单)是:

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

#6


1  

JavaScript: addEventListener method registers the specified listener on the EventTarget(Element|document|Window) it's called on.

addEventListener方法在它调用的EventTarget(元素|document|窗口)上注册指定的监听器。

EventTarget.addEventListener(event_type, handler_function, Bubbling|Capturing);

EventTarget。addEventListener(event_type handler_function,泡泡|捕获);

Mouse, Keyboard events Example test in WebConsole:

鼠标、键盘事件示例测试在WebConsole中:

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 method removes the event listener previously registered with EventTarget.addEventListener().

removeEventListener方法删除先前已注册为EventTarget.addEventListener()的事件监听器。

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

caniuse

caniuse

#7


1  

To give a more up-to-date approach to this:

就这方面提出更先进的方法:

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

#8


0  

This is not ideal as it removes all, but might work for your needs:

这并不理想,因为它消除了一切,但可能适合您的需要:

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

Cloning a node copies all of its attributes and their values, including intrinsic (in–line) listeners. It does not copy event listeners added using addEventListener()

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

Node.cloneNode()

Node.cloneNode()

#9


0  

Possibly not the best solution in terms of what you are asking. I have still not determined an efficient method for removing anonymous function declared inline with the event listener invocation.

就你的要求而言,这可能不是最好的解决方案。我还没有确定一个有效的方法来删除与事件侦听器调用内联的匿名函数。

I personally use a variable to store the <target> and declare the function outside of the event listener invocation eg:

我个人使用一个变量来存储 ,并在事件监听器调用之外声明函数:

const target = document.querySelector('<identifier>');

const目标= document.querySelector(“ <标识符> ”);

function myFunc(event) { function code; }

函数myFunc(事件){函数代码;}

target.addEventListener('click', myFunc);

目标。addEventListener(“点击”,myFunc);

Then to remove the listener:

然后移除监听器:

target.removeEventListener('click', myFunc);

目标。removeEventListener(“点击”,myFunc);

Not the top recommendation you will receive but to remove anonymous functions the only solution I have found useful is to remove then replace the HTML element. I am sure there must be a better vanilla JS method but I haven't seen it yet.

我发现唯一有用的解决方案是删除然后替换HTML元素。我相信肯定有更好的JS方法,但我还没见过。

#10


-4  

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