JS: не могу удалить eventListener для моей функции устранения дребезга

 let header = document.getElementById('header');

function logTitle() {
    console.info("Logging Title")
}

let debounceFunc = function debounce(fn, delay) {
    let newFn;

    return function(...args) {
       if (newFn) {
          clearTimeout(newFn);
       }
       newFn = setTimeout(() => {
           fn(...args)
       },delay);
 
    }
}


header.addEventListener('click', debounceFunc(logTitle, 3000));

Протестировал это и работает так, как ожидалось. Затем, когда я пытаюсь удалить его, у меня возникают проблемы:

header.removeEventListener('click', debounceFunc);

Я также пробовал header.removeEventListener('click', debounceFunc, true) и header.removeEventListener('click', debounceFunc, false);, но ни один из них не удаляется.

Любые идеи, что я делаю неправильно?

Обновлено: я также пытался изначально создать debounce, не устанавливая для него такую ​​​​переменную, и просто привязал debounce к clickEvent, но это не сработало и при удалении:

// tried creating function like this as well: 
function debounce(fn, delay) {
    let newFn;

    return function(...args) {
       if (newFn) {
          clearTimeout(newFn);
       }
       newFn = setTimeout(() => {
           fn(...args)
       },delay);
 
    }
}

Где выполняется удаление прослушивателя событий?

Faraz 10.12.2020 08:52

@FarazShaikh Я делаю все это в консоли браузера, поэтому я выполняю удаление прослушивателя событий, проверяя его, щелкнув элемент в DOM, и он не работает.

LegoGeo 10.12.2020 08:54

Я думаю, проблема в том, что debounceFunc при оценке addEventListner возвращает анонимную функцию, то есть функцию, которая добавляется в eventListener, а не debounceFunc. Вы должны сохранить ссылку на эту анонимную функцию, после чего вы сможете использовать эту ссылку в removeEvenrListner

Faraz 10.12.2020 08:57

@FarazShaikh, но это не debounceFunc в конечном счете функция, прикрепленная к eventListener, и ее удаление должно удалить все внутри, верно?

LegoGeo 10.12.2020 09:02

Нет, вы не передаете ссылку на debounceFunc, вы вызываете denounceFunc, который сначала оценивает его, а затем прикрепляет возвращенную из него функцию. Как только вы поставите () после имени функции, она станет вызовом функции.

Faraz 10.12.2020 09:03

@FarazShaikh ты был прав, спасибо

LegoGeo 10.12.2020 09:15

Приветствуются голоса :)

Faraz 10.12.2020 09:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
7
625
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Ваша проблема заключается в попытке removeEventListener, когда слушатель является анонимной функцией. Это невозможно. Однако вы можете присвоить возвращаемое значение debounceFunc переменной, например my_callback. После этого my_callback становится функцией. Затем просто передайте my_callback, чтобы добавить/удалить EventListener.

Просто используйте это:

let header = document.getElementById('header');

function logTitle() {
    console.info("Logging Title")
}

let debounceFunc = function debounce(fn, delay) {
    let newFn;

    return function(...args) {
       if (newFn) {
          clearTimeout(newFn);
       }
       newFn = setTimeout(() => {
           fn(...args)
       },delay);
 
    }
}

let my_callback = debounceFunc(logTitle, 3000);

header.addEventListener('click', my_callback);

А затем удалить с помощью этого вызова функции:

header.removeEventListener('click', my_callback);

Ответ не содержит объяснений (я не против)

ISD 10.12.2020 09:00

@Vlad let debounceFunc = function debounce(fn, delay) { } по-прежнему считается анонимной функцией, хотя функция названа?

LegoGeo 10.12.2020 09:10

@LegoGeo нет, анонимная функция - это безымянная функция. В вашем коде это объявлено в строке return function(...args) {

Vlad Havriuk 10.12.2020 09:11

Кстати, вы тоже можете использовать let debounceFunc = function (fn, delay) {, назначив анонимную функцию переменной debounceFunc

Vlad Havriuk 10.12.2020 09:12

спасибо ... так что это хороший способ подумать об этом: у меня было так, когда он каждый раз вызывал новую функцию, поэтому нет никакого способа удалить это - решение состоит в том, чтобы сохранить его в переменной, поэтому что это может быть удалено/сослано на более позднюю дату?

LegoGeo 10.12.2020 09:18

@LegoGeo Единственная разница между вашим старым кодом и этим кодом заключается в сохранении возвращаемого значения debounceFunc. Таким образом, функция не генерировалась каждый раз, вы просто не могли получить доступ к такой функции

Vlad Havriuk 10.12.2020 09:23

это просто заставило меня щелкнуть в моей голове, большое спасибо

LegoGeo 10.12.2020 09:24

Вы должны сохранить дескриптор для прослушивателя событий и отвязать прослушиватель событий по дескриптору. Так:

let header = document.getElementById('header');

function logTitle() {
    console.info("Logging Title")
}

let debounceFunc = function debounce(fn, delay) {
    let newFn;

    return function(...args) {
       if (newFn) {
          clearTimeout(newFn);
       }
       newFn = setTimeout(() => {
           fn(...args)
       },delay);
 
    }
}

const eventHandler = debounceFunc(logTitle, 300);

header.addEventListener('click', eventHandler);

document.querySelector('button').addEventListener('click', () => {
  header.removeEventListener('click', eventHandler);
})
<header id = "header">
I'm header, click me to debounce function
</header>
<button>
Click me to unbind event handler for header
</button>

это работает, спасибо, но теперь я в замешательстве, почему ... почему это работает, когда я устанавливаю переменную как debounceFunc ( const eventHandler = debounceFunc(logTitle, 300); ) вот так?

LegoGeo 10.12.2020 09:05

Другие вопросы по теме