AddEventListener и removeEventListener разное поведение в Firefox / Chrome против Edge

Недавно я столкнулся со странной непоследовательностью в том, как Edge выполнял часть Javascript по сравнению с Chrome и Firefox.

При подключении обработчика кликов (неправильного, случайно) Edge отреагировал, как и следовало ожидать. Но Chrome и Firefox проигнорировали неправильный обработчик кликов, скрыв мою ошибку.

button.addEventListener("click", functionOne);

function functionOne(e) {
  console.info('functionOne called');
  functionTwo(e);
}

function functionTwo(e) {
  console.info('functionTwo called');
  
  // My intial mistake was here: According to my application logic, 
  // I should have removed the event listener for functionOne. Whoops.
  button.removeEventListener("click", functionThree);
  
  console.info("Doing some asynchronous work...");
  
  // Same here: I should have re-added the event listener for functionOne
  button.addEventListener("click", functionThree);
}

// This function is never called by FF and Chrome, but it is called in Edge
function functionThree(e) {
  console.error('functionThree called');
}

Я намеревался удалить прослушиватель событий для functionOne, пока выполнял некоторую асинхронную работу, а затем повторно подключить его после завершения асинхронного вызова. Моя ошибка заключалась в вызове removeEventListener() со ссылкой на неправильную функцию (functionThree), а затем в подключении другого прослушивателя событий к button, который также вызывает functionThree.

Но, как ни странно, код работал так, как задумано в Chrome и Firefox. Только когда я попробовал это в Edge, я заметил, что Edge вызывает functionThree, в то время как Chrome и Firefox игнорируют его.

Может кто-нибудь объяснить такое поведение? Почему Chrome и Firefox не вызывают functionThree, хотя я подключил прослушиватель событий? Почему делает Edge называет это?

Версии браузера:

 FireFox  59.0.2
 Edge     41.16299.371.0 
 Chrome   66.0.3359.139

TL; DR - Firefox / Chrome не подключил прослушиватель событий, как я ожидал. Эдж сделал.

Ссылка на пример jsbin

Поведение ключевого слова "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) для оценки ваших знаний,...
0
0
295
1

Ответы 1

По моим наблюдениям, разница заключается в следующем:

  • В BOTH chrome / firefox и т. Е. Добавленный eventListener будет срабатывать не для текущего события, а для следующего события.
  • В chrome / firefox удаленный прослушиватель событий немедленно предотвращает вызов обработчика WHEREAS, т.е. обработчики, уже подключенные к элементу, будут срабатывать, но эффект removeEventListener будет иметь место в следующий тик движка.

Вот почему в ОБЕИХ случаях (т.е. и firefox / chrome) первый щелчок не будет запускать функцию-3, но последующие щелчки будут запущены, т.е. Чтобы исправить такое поведение, я могу добавить, например, к stopImmediatePropagation:

function functionTwo(e) {

  console.info('functionTwo called');

  // My intial mistake was here: I put functionThree in by accident
  // and only then noticed the strange behaviour
  button.removeEventListener("click", functionThree);

  console.info("Doing some asynchronous work...");

  // Same here: I should have put functionOne as the second argument
  button.addEventListener("click", functionThree);
  e.stopImmediatePropagation();
}

Теперь то есть будет вести себя как firefox / chrome.

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