addEventListener и removeEventListener различное поведение в FF / Chrome против Edge - PullRequest
0 голосов
/ 04 мая 2018

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

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

button.addEventListener("click", functionOne);

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

function functionTwo(e) {
  console.log('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.log("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 - FF / Chrome не подключил прослушиватель событий, как я ожидал. Эдж сделал.

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

1 Ответ

0 голосов
/ 04 мая 2018

По моим наблюдениям, разница проистекает из того факта:

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

Вот почему в ОБА (в случае Firefox / Chrome) первый щелчок не вызовет функцию-3, но последующие щелчки будут выполнены, т.е. Чтобы исправить это поведение, мое решение состоит в том, чтобы добавить к stopImmediatePropagation:

function functionTwo(e) {

  console.log('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.log("Doing some asynchronous work...");

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

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

...