removeEventListner () не влияет - PullRequest
       34

removeEventListner () не влияет

0 голосов
/ 30 апреля 2020

Я пытаюсь сделать карточную игру. В моей игре пользователь обязан выбрать одну из карт (я добавляю EventListeners к каждой карточке, что составляет <img> в моей HTML), и после выбора ему нельзя разрешать нажимать на любую другую карту (я должен удалить все 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);
            }
        });
    }
};

1 Ответ

1 голос
/ 30 апреля 2020

При щелчке удаляемая _listener - это функция _listener, определенная в этом l oop:

for (card of myCardBox){
    card.addEventListener("click", function _listener(choosen_card) {

На каждой итерации вы определяете новая _listener функция. Поэтому, когда вы делаете

card.removeEventListener("click", _listener);

внутри l oop, вы ссылаетесь на _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
    });
  });
};
...