removeEventListener() 不生效

removeEventListner() does not take affect

我正在尝试制作纸牌游戏。在我的游戏中,用户有义务选择一张卡片(我将 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) {

每次迭代,您定义一个 new _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 的函数。

改用事件委托怎么样?只向容器添加一个侦听器,并在每次点击时将其删除。

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
    });
  });
};