我正在尝试制作一款纸牌游戏。在我的游戏中,用户有义务选择一张卡(我向每张卡添加 EventListeners
,在我的 HTML 中为 <img>
),选择后他不应该允许点击任何其他卡(我必须删除所有 EventListeners
)。
由于某些原因,此代码没有删除 EventListeners
,但我仍然能够执行操作。我想避免在 addEventListener()
之外创建单独的函数。
MessageHandler.prototype.give_card_to_next_player = function (evt) {
let myCardBox = document.getElementById("my-hand").childNodes;
for (card of myCardBox){
card.addEventListener("click", function _listener(choosen_card) {
message_handler.sendMessage({
"type": "give_away_card",
"choosen_card": [...myCardBox].indexOf(choosen_card.target),
"for_player": evt.nextPlayer
});
choosen_card.target.remove();
for (card of myCardBox){
card.removeEventListener("click", _listener);
}
});
}
};
最佳答案
当点击时,您删除的 _listener
是在该循环中定义的 _listener
函数:
for (card of myCardBox){
card.addEventListener("click", function _listener(choosen_card) {
每次迭代,您都会定义一个新 _listener
函数。所以当你这样做时
card.removeEventListener("click", _listener);
在循环内,您仅针对该迭代引用 _listener
- 仅针对该 card
。因此,只有该卡的监听器被删除 - 其他卡有一个监听器,它是不同函数引用。
出于同样的原因,下面代码片段中的函数不是 ===
。
const fns = [];
for (let i = 0; i < 2; i++) {
fns.push(function foo(){});
}
console.log(fns[0] === fns[1]);
removeEventListener
只会删除与之前传递给 addEventListener
的函数 ===
相同的函数。
使用事件委托(delegate)怎么样?仅向容器添加一个监听器,并在单击时将其删除。
MessageHandler.prototype.give_card_to_next_player = function (evt) {
const hand = document.getElementById("my-hand");
const cards = [...hand.children];
hand.addEventListener('click', function handleClick(e) {
const target = e.target;
// if click was on the container but not on any cards, don't do anything
if (target === hand) return;
// Remove event listener
hand.removeEventListener('click', handleClick);
// Calculate index, send message
const index = cards.indexOf(target);
message_handler.sendMessage({
"type": "give_away_card",
"choosen_card": index,
"for_player": evt.nextPlayer
});
});
};
关于javascript - removeEventListener() 不生效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61513301/