Почему событие срабатывает более одного раза?

Для истинного логического значения в eventListeners я прочитал здесь:

once: A Boolean indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.

window.addEventListener("keydown", function(event){
    switch(event.code){
        case 'Digit1': 
            shoot('Ball1');
            break;

        case 'Digit2':
            shoot('Ball2');
            break;
    }
}, true);

В моем коде функция съемки называется бесконечной. Почему?

И как это исправить? Функция Shot () может запускаться только один раз.

В соответствии с рекомендациями я изменил "true" на "{once: true}". Он по-прежнему называет Shot () бесконечным. У тебя есть идея, почему?

Спасибо @CertainPerformance.

Если у вас возникнет такая же проблема, имейте в виду, что Internet Explorer не знает event.code.

Может быть, вы добавляете прослушиватель событий более одного раза?

yossico 22.11.2018 08:30

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

NewbieXXL 22.11.2018 08:33
Поведение ключевого слова "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) для оценки ваших знаний,...
2
2
74
2

Ответы 2

Третий параметр, предоставляемый addEventListener, - это либо, optionsобъект, или useCapture, логическое значение. Поскольку вы передали логическое значение, интерпретатор считает, что вы указали, что хотите, чтобы функция запускалась в фазе захвата, а не в фазе восходящей цепочки, что вас не волнует.

Вместо этого передайте объект options со свойством once:

window.addEventListener(
  "keydown",
  function(event){
    switch(event.code){
      case 'Digit1': 
        shoot('Ball1');
        break;

      case 'Digit2':
        shoot('Ball2');
        break;
    }

  },
  { once: true }
);

window.addEventListener(
  "keydown",
  function(event){
    console.info('function running');
  },
  { once: true }
);

Internet Explorer и другие более старые версии браузеров не поддерживаю вариант once, поэтому для поддержки IE вам придется написать немного больше кода - вручную удалить слушатель после его запуска:

function listener() {
  console.info('function running');
  window.removeEventListener("keydown", listener);
}
window.addEventListener("keydown", listener);

Или с switch:

window.addEventListener("keydown", listener);

function listener(event) {
  console.info('function running');
  window.removeEventListener("keydown", listener);

  switch (event.code) {
    case 'Digit1':
      shoot('Ball1');
      break;

    case 'Digit2':
      shoot('Ball2');
      break;
  }
}

Опять же, с другими случаями switch:

window.addEventListener("keydown", listener); 

function listener(event) { 
  console.info('function running'); 
  window.removeEventListener("keydown", listener); 

  switch(event.code){ 
    case 'Digit1': 
      shoot('Ball1'); 
      break; 

    case 'Digit2': 
      shoot('Ball2'); 
      break; 

    case 'Digit3': 
      shoot('Ball3'); 
      break; 

    case 'Digit4': 
      shoot('Ball4'); 
      break; 
  }
}

Я пробовал безуспешно. Это не работает в chrome или explorer :-(

NewbieXXL 22.11.2018 08:35

См. Фрагмент, отредактированный в ответ, отлично работает для меня

CertainPerformance 22.11.2018 08:37

Для устаревших браузеров, таких как IE, вы не можете использовать опцию once, вам придется делать это вручную с помощью removeEventListener. Похоже, браузеры реализовали это примерно в конце 2016 года.

CertainPerformance 22.11.2018 08:41

Я заменил {once: true} на функцию "слушателя" и добавил эту функцию в свой код. chrome по-прежнему показывает бесконечное поведение, а iexplorer не реагирует на нажатие клавиши.

NewbieXXL 22.11.2018 08:47

Я тестировал его как в Chrome, так и в IE11, слушатель действительно запускается один раз, а затем удаляется. Вы проверили последний живой фрагмент в ответе?

CertainPerformance 22.11.2018 08:49

Позвольте нам продолжить обсуждение в чате.

NewbieXXL 22.11.2018 08:51

Добавляемый вами параметр boolean не указывает, что обработчик событий должен выполняться только один раз. Это относится к захвату событий.

Чтобы обработчик выполнялся только один раз, вам необходимо передать объект параметров:

window.addEventListener("keydown", function(event) { /* ... */ }, {once: true});

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