javascript - removeEventListener() 不生效

标签 javascript dom-events

我正在尝试制作一款纸牌游戏。在我的游戏中,用户有义务选择一张卡(我向每张卡添加 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/

相关文章:

javascript - Vue.js 直接在模板中的 v-for 中引用存储的不好做法?

javascript - jQuery 表单验证插件 : Return false on error

javascript - Shift 单击以在不使用 Angular Directive(指令)的情况下为对象添加值

javascript - 从使用 JavaScript 未打开弹出窗口的窗口关闭弹出窗口

javascript - jQuery:为什么触发器不会从 JS 对象触发?

javascript - JavaScript 中的单链表中的 Set 如何与 Get 一起使用?

javascript - Javascript:嵌套函数中的切换 bool 值未更改

javascript - 在鼠标按下期间获取鼠标位置?

javascript - 事件捕获与事件冒泡

javascript - 处理浏览器中的后退按钮事件