我还是JavaScript的新手,但遇到了以下问题。
我想命名/声明我的函数,然后将其名称用作侦听器以轻松添加/删除点击事件。主要原因是这样,只要发生某种情况,我就可以删除点击事件。
我要实现的目标的简要说明:
function game() {
//
}
我遇到的问题是当我添加这样的事件时:
for (let i = 0; i < cards.length; i++) {
card = cards[i];
card.addEventListener('click', game);
}
命名函数游戏出现错误,提示:
我没有定义
但是,当我将函数作为匿名函数放在侦听器参数中时,不会发生此错误。
for (let i = 0; i < cards.length; i++) {
card = cards[i];
card.addEventListener('click', function game() {
//
}
全局声明i
不起作用,也没有传递i
作为参数。
答案 0 :(得分:1)
要访问不同的i
,您需要使用不同的闭包,因此您将获得不同的函数引用。您可以将它们直接存储在卡中,以便以后将其删除:
for (let i = 0; i < cards.length; i++) {
const card = cards[i];
card.addEventListener('click', card._click = function game() {
//
});
}
然后您可以通过以下方式将其删除:
card.removeEventListener("click", card._click);
如果您将game
移到外面并为i
添加一个咖喱参数(可能会更干净),也可以这样做:
const game = i => () => {
// ...
};
for (let i = 0; i < cards.length; i++) {
const card = cards[i];
card.addEventListener('click', card._click = game(i));
}
答案 1 :(得分:0)
您的问题是您的game
函数不了解i
,因为由于变量作用域的原因,i
中的game
不存在。为了解决这个问题,您可以像这样将i
作为参数传递给game
:
card.addEventListener('click', _ => game(i));
在上一行中,您调用了箭头函数,然后调用了game
函数。这使您可以将参数传递到game
中。
然后在您的game
方法中接受变量i
作为参数:
function game(i) {
请参阅工作示例here
答案 2 :(得分:0)
您应该在JavaScript中阅读有关lexical scoping
的信息,以了解为什么i
在命名函数game
中不可用
游戏内部函数只能引用词法范围内的变量(或本身在主题this
中的变量)
简单地说,您可以将'i'传递给游戏以使其正常运行。但是由于addEventListener需要函数,因此您应该创建一个使用closure
以
修改游戏let game = (i) => () => {
//existing game function
}
现在使用card.addEventListener('click', game(i));
,它应该可以正常工作
这里有个有用的小提琴供您参考:https://jsfiddle.net/uch1arny/2/