JS - Как удалить активный прослушиватель событий без перезагрузки веб-страницы

У меня есть функция playGame(), которая инициирует прослушиватель событий. Каждый раз, когда запускается новая игра, функция playGame() создает дополнительный обработчик событий. Как я могу удалить активный eventListener, чтобы каждый раз, когда игра играется, новый не добавлялся.

Я попытался использовать removeEventListener, как описано здесь — https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener . Я также просматривал похожие проблемы с переполнением стека (например, удаление прослушивателей событий перед выходом из page ), но решение там не применялось.

Вот как устроена функция. Я пытаюсь удалить старый eventListener перед загрузкой остальных игровых скриптов.

function playGame() {
    console.log('new game');
    // should remove event listener from previous game
    document.removeEventListener('keyup', function() {userInput(activeStringObj, event.key);});

    loadStartOutput();
    wordPicker(activeStringObj);
    addLetterDivs(activeStringObj); 
    addHint(activeStringObj);

    document.addEventListener('keyup', function() {userInput(activeStringObj, event.key);});
}

Я регистрирую массив, который записывает нажатия клавиш пользователями, и очевидно, что несколько прослушивателей событий записывают входные данные.

new game (typed 'a' 's')

game.js:98 ["a"]

game.js:98 (2) ["a", "s"]

new game (typed 'd' 'f')

game.js:98 (3) ["a", "s", "d"]

game.js:98 (4) ["a", "s", "d", "d"]

game.js:98 (5) ["a", "s", "d", "d", "f"]

game.js:98 (6) ["a", "s", "d", "d", "f", "f"]

new game (typed 'h' 'j')

game.js:98 (7) ["a", "s", "d", "d", "f", "f", "h"]

game.js:98 (8) ["a", "s", "d", "d", "f", "f", "h", "h"]

game.js:98 (9) ["a", "s", "d", "d", "f", "f", "h", "h", "h"]

game.js:98 (10) ["a", "s", "d", "d", "f", "f", "h", "h", "h", "j"]

game.js:98 (11) ["a", "s", "d", "d", "f", "f", "h", "h", "h", "j", "j"]

game.js:98 (12) ["a", "s", "d", "d", "f", "f", "h", "h", "h", "j", "j", "j"]

Я ожидаю, что при каждом нажатии клавиши в массив будет добавляться только одна буква.


person Lewis Lockhart    schedule 31.10.2019    source источник
comment
Возможно ли, что вместо того, чтобы eventListener не удалялся, он инициировался дважды?   -  person Edrian    schedule 31.10.2019
comment
Это хорошее соображение. Однако кажется, что при запуске игры после обновления страницы добавляется только один. После этого каждый раз, когда игра перезапускается, кажется, что к массиву добавляется только один дополнительный слушатель.   -  person Lewis Lockhart    schedule 31.10.2019


Ответы (2)


При добавлении и удалении прослушивателей событий функция обработчика (включая сигнатуру функции) должна быть одинаковой. В вашем коде вы написали идентичное определение функции дважды! Это означает, что одна и та же функция объявляется дважды. Это не та функция. Вместо этого попробуйте следующее:

function takeAction(event) {
    userInput(activeStringObj, event.key)
}

function playGame() {
    console.log('new game');
    // should remove event listener from previous game
    document.removeEventListener('keyup', takeAction);

    loadStartOutput();
    wordPicker(activeStringObj);
    addLetterDivs(activeStringObj); 
    addHint(activeStringObj);

    document.addEventListener('keyup', takeAction);
}

Это должно сделать работу за вас.

person Vikram Deshmukh    schedule 31.10.2019

вам нужно передать одну и ту же функцию для удаления по указателю, тела функций одинаковы, но они не являются одним и тем же объектом, это 2 отдельных указателя на 2 разных объекта функций с одним и тем же телом.

Или добавьте прослушиватель событий один раз и передайте обработчику текущий игровой объект, который у вас есть в качестве аргумента.

person Sergey Sahakyan    schedule 31.10.2019