需要参数的 addEventListener(和 removeEventListener)函数
addEventListener (and removeEventListener) function that need param
我需要为 8 个对象(手掌)添加一些侦听器。
这些对象是相同的,但行为必须根据它们的位置而改变。
我有以下(丑陋的)代码:
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); });
我有两个需求:
1) 不对点击事件使用匿名函数。
我写了这段代码,但它不起作用
root.game.palms.palm8.addEventListener("click", palmShakeHandler(8));
所以这个很好用
root.game.palms.palm8.addEventListener("click", function(){ palmShakeHandler(8); });
但是我不明白如何删除事件侦听器。
我尝试了这个解决方案,但它不起作用
root.game.palms.palm8.addEventListener("click", palmHandler = function(){ palmShakeHandler(8); });
root.game.palms.palm8.removeEventListener("click", palmHandler);
2) 在 for 循环中添加和删除侦听器
我写了以下代码,但行为不正确。
for (i=1; i <= root.palmsStatus.length; i++){
if (root.palmsStatus[i-1] !== "N"){
root.game.palms["palm" + i].addEventListener("click", function(){ palmShakeHandler(i); });
}
}
已添加侦听器,但传递给 palmShakeHandler 的参数值始终为 8。
没有人可以帮我解决这些问题吗?
在 JavaScript 中使用 Function.prototype.bind
方法实际上是一种完美的方法。
bind
允许您定义将作为参数传递给函数的额外参数。
您还应该记住,bind
创建了一个新函数并且不修改初始函数。
这是它的样子:
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
这应该可以解决您的问题,您将能够轻松删除处理程序:)
您的代码将如下所示:
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));
}
}
为了之后能够删除处理程序,您需要保留对使用 bind
创建的函数的引用。这就是执行此操作的方法。
var boundHandler = handler.bind(null, i);
element.addEventListener(boundHandler);
element.removeEventListener(bounderHander);
如果您想了解更多关于 JavaScript 中令人敬畏的 bind
方法的信息,MDN 是您的朋友:) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
顺便说一句,你的函数总是返回 8
的问题在 JavaScript 中是一个很常见的问题。该线程将解释所有内容(剧透,这是范围界定的问题:))
在上一个解决方案中,您将相同的 var 传递给每个函数,这就是使所有函数都使用 8 的原因,因为 8 是变量的最后一个值。
为了解决问题,您可以使用 "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);
}
}
因为它看起来像是您针对的是现代浏览器,所以我将使用 let。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)};
}
}
所以现在你只需要调用 "removeHandShake" 并删除监听器,
我这里有这个代码,所以它可以减少弹出的一些小错误
因此,如果您的 »palms« 数组非常大,为每个数组添加一个事件侦听器基本上不是一个好主意,因为这会导致性能缺陷。所以我建议采用不同的方法:
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);
}
})
所有人的一个事件侦听器,更容易删除并且性能更好。
我需要为 8 个对象(手掌)添加一些侦听器。 这些对象是相同的,但行为必须根据它们的位置而改变。 我有以下(丑陋的)代码:
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); });
我有两个需求:
1) 不对点击事件使用匿名函数。
我写了这段代码,但它不起作用
root.game.palms.palm8.addEventListener("click", palmShakeHandler(8));
所以这个很好用
root.game.palms.palm8.addEventListener("click", function(){ palmShakeHandler(8); });
但是我不明白如何删除事件侦听器。 我尝试了这个解决方案,但它不起作用
root.game.palms.palm8.addEventListener("click", palmHandler = function(){ palmShakeHandler(8); });
root.game.palms.palm8.removeEventListener("click", palmHandler);
2) 在 for 循环中添加和删除侦听器
我写了以下代码,但行为不正确。
for (i=1; i <= root.palmsStatus.length; i++){
if (root.palmsStatus[i-1] !== "N"){
root.game.palms["palm" + i].addEventListener("click", function(){ palmShakeHandler(i); });
}
}
已添加侦听器,但传递给 palmShakeHandler 的参数值始终为 8。
没有人可以帮我解决这些问题吗?
在 JavaScript 中使用 Function.prototype.bind
方法实际上是一种完美的方法。
bind
允许您定义将作为参数传递给函数的额外参数。
您还应该记住,bind
创建了一个新函数并且不修改初始函数。
这是它的样子:
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
这应该可以解决您的问题,您将能够轻松删除处理程序:)
您的代码将如下所示:
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));
}
}
为了之后能够删除处理程序,您需要保留对使用 bind
创建的函数的引用。这就是执行此操作的方法。
var boundHandler = handler.bind(null, i);
element.addEventListener(boundHandler);
element.removeEventListener(bounderHander);
如果您想了解更多关于 JavaScript 中令人敬畏的 bind
方法的信息,MDN 是您的朋友:) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
顺便说一句,你的函数总是返回 8
的问题在 JavaScript 中是一个很常见的问题。该线程将解释所有内容(剧透,这是范围界定的问题:))
在上一个解决方案中,您将相同的 var 传递给每个函数,这就是使所有函数都使用 8 的原因,因为 8 是变量的最后一个值。
为了解决问题,您可以使用 "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);
}
}
因为它看起来像是您针对的是现代浏览器,所以我将使用 let。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)};
}
}
所以现在你只需要调用 "removeHandShake" 并删除监听器,
我这里有这个代码,所以它可以减少弹出的一些小错误
因此,如果您的 »palms« 数组非常大,为每个数组添加一个事件侦听器基本上不是一个好主意,因为这会导致性能缺陷。所以我建议采用不同的方法:
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);
}
})
所有人的一个事件侦听器,更容易删除并且性能更好。