[英]addEventListener (and removeEventListener) function that need param
I need to add some listeners to 8 object (palms). 我需要向8个对象(手掌)添加一些侦听器。 These object are identical but the behaviour have to change basing to their position. 这些对象是相同的,但是行为必须根据其位置进行更改。 I have the follow (ugly) code: 我有以下(丑陋的)代码:
root.palmsStatus = ["B","B","B","B","B","B","B","B"];
if (root.palmsStatus[0] !== "N")
root.game.palms.palm1.addEventListener("click", palmHandler = function(){ palmShakeHandler(1); });
if (root.palmsStatus[1] !== "N")
root.game.palms.palm2.addEventListener("click", palmHandler = function(){ palmShakeHandler(2); });
if (root.palmsStatus[2] !== "N")
root.game.palms.palm3.addEventListener("click", function(){ palmShakeHandler(3); });
if (root.palmsStatus[3] !== "N")
root.game.palms.palm4.addEventListener("click", function(){ palmShakeHandler(4); });
if (root.palmsStatus[4] !== "N")
root.game.palms.palm5.addEventListener("click", function(){ palmShakeHandler(5); });
if (root.palmsStatus[5] !== "N")
root.game.palms.palm6.addEventListener("click", function(){ palmShakeHandler(6); });
if (root.palmsStatus[6] !== "N")
root.game.palms.palm7.addEventListener("click", function(){ palmShakeHandler(7); });
if (root.palmsStatus[7] !== "N")
root.game.palms.palm8.addEventListener("click", function(){ palmShakeHandler(8); });
I have two needs: 我有两个需求:
1) doesn't use an anonymous function on click event. 1)在点击事件上不使用匿名函数。
I wrote this code, but it doesn't work 我写了这段代码,但是没有用
root.game.palms.palm8.addEventListener("click", palmShakeHandler(8));
So this one works fine 所以这个很好用
root.game.palms.palm8.addEventListener("click", function(){ palmShakeHandler(8); });
But I didn't understand how remove the event listener. 但是我不明白如何删除事件监听器。 I try this solution, but it doesn't work 我尝试了此解决方案,但没有用
root.game.palms.palm8.addEventListener("click", palmHandler = function(){ palmShakeHandler(8); });
root.game.palms.palm8.removeEventListener("click", palmHandler);
2) add and remove listener in a for cycle 2)在for周期中添加和删除侦听器
I wrote the follow code but the behaviour is not correct. 我编写了以下代码,但行为不正确。
for (i=1; i <= root.palmsStatus.length; i++){
if (root.palmsStatus[i-1] !== "N"){
root.game.palms["palm" + i].addEventListener("click", function(){ palmShakeHandler(i); });
}
}
the listeners was added but the value of the parameter passed to the palmShakeHandler is always 8. 添加了侦听器,但传递给palmShakeHandler的参数的值始终为8。
Nobody could help me to fix these issues? 没有人能帮助我解决这些问题吗?
There is a actually, a perfect way to do that in JavaScript using the Function.prototype.bind
method. 使用Function.prototype.bind
方法,在JavaScript中实际上是一种完美的方法。
bind
let you define extra parameters that will be passed, as arguments, of the function. bind
使您可以定义额外的参数,这些参数将作为函数的参数传递。
You should also keep in mind that bind
creates a new function and doesn't modify the initial function. 您还应该记住, bind
会创建一个新函数,并且不会修改初始函数。
Here is what it looks like: 看起来像这样:
function palmHandler(number) {
// your code working with `number`
}
var palmHandler8 = palmHandler.bind(null, 8)
// the palmHandler8 is now tied to the value 8.
// the first argument (here null) define what `this` is bound to in this function
This should fix your problem, and you will be able to remove handlers easily :) 这应该可以解决您的问题,并且您将能够轻松删除处理程序:)
Your code will look like this: 您的代码将如下所示:
for (i=1; i <= root.palmsStatus.length; i++){
if (root.palmsStatus[i-1] !== "N"){
root.game.palms["palm" + i].addEventListener("click", palmShakeHandler.bind(null, i));
}
}
To be able to remove the handler afterward, you need to keep a reference to the function you create with bind
. 为了能够在以后删除处理程序,您需要保留对使用bind
创建的函数的引用。 This would be the way to do this. 这就是这样做的方法。
var boundHandler = handler.bind(null, i);
element.addEventListener(boundHandler);
element.removeEventListener(bounderHander);
If you want to know more about the awesome bind
method in JavaScript, the MDN is your friend :) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind 如果您想了解有关JavaScript中很棒的bind
方法的更多信息,那么MDN是您的朋友:) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
BTW, the problem with you function always returning 8
is a very common question in JavaScript. 顺便说一句,您的函数始终返回8
问题是JavaScript中一个非常常见的问题。 This thread will explain everything (spoiler, it's a matter of scoping :) ) https://stackoverflow.com/a/750506/2745879 该线程将解释所有内容(破坏者,这是范围界定的问题:)) https://stackoverflow.com/a/750506/2745879
In your last solution you are pasing the same var to every function and that is what make al the functions work with 8 because is the last value of the variable. 在您的最后一个解决方案中,您要向每个函数粘贴相同的var,这就是使函数与8一起使用的原因,因为它是变量的最后一个值。
To work arround that you can use "let" ( please at least use var, otherside that "i" is global and can be changed every where in the code) but since I dont know wich browser you target I propose other solution. 为了工作,您可以使用“ let”(至少请使用var,否则“ i”是全局的,并且可以在代码中的每个位置更改),但是由于我不知道您所针对的浏览器,因此我建议使用其他解决方案。
for (var i=1; i <= root.palmsStatus.length; i++){
if (root.palmsStatus[i-1] !== "N"){
root.game.palms["palm" + i].addEventListener("click", (function(index)
(return function(){
palmShakeHandler(index);
}))(i);
}
}
Since its look like You are targeting modern browsers I will use let. 由于它看起来像您正在针对现代浏览器,因此我将使用let。 https://kangax.github.io/compat-table/es6/ https://kangax.github.io/compat-table/es6/
for (var i=1; i <= root.palmsStatus.length; i++){
let index = i;
let intermediateFunction = function(){palmShakeHandler(index);};
if (root.palmsStatus[i-1] !== "N"){
root.game.palms["palm" + i].addEventListener("click",intermediateFunction);
root.game.palms["palm" + i].removeHandShake = function(){this.removeEventListener("click",intermediateFunction)};
}
}
So now you just need to call "removeHandShake" and will remove the listener, 因此,现在您只需要调用“ removeHandShake”即可删除监听器,
I have code this right here so it ease some minor errors to pop 我在这里有此代码,因此可以缓解一些小错误
So in case your array of »palms« is very huge, it is basically a bad Idea to add a single event listener to each of them, because that causes performance flaws. 因此,如果您的»palm«数组非常庞大,则向其中的每个事件添加单个事件侦听器基本上是一个糟糕的主意,因为这会导致性能缺陷。 So I would suggest a different approach: 因此,我建议采用另一种方法:
var handlers = [function (e) {}, …, function (e) {}];
root.game.palms.forEach(functiion (palm, idx) {
palm.setAttribute('data-idx', idx);
});
<palmsparent>.addEventListener('click', function (e) {
var c = e.target, idx = -1;
while (c) {
if (c.hasAttribute && c.hasAttribute('data-idx')) {
idx = parseInt(c.getAttribute('data-idx'));
break;
}
c = c.parentNode;
}
//here you also check for the »palm status«
if (idx >= 0) {
handlers[idx](c);
}
})
One event listener for all, much easier to remove and better for performance. 所有人都可以使用一个事件侦听器,更容易删除并且可以提高性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.