Что я ожидаю от своего кода. Когда я нажимаю первую кнопку, а затем нажимаю клавишу пробела, он должен предупредить "привет, мир". Когда я нажимаю вторую кнопку, а затем нажимаю клавишу пробела, я ожидаю, что это ...

0
coder 10 Апр 2021 в 09:39

1 ответ

Лучший ответ

В настоящее время, когда вы нажимаете Пробел , все прослушиватели событий по-прежнему привязаны (по нажатию кнопки), и каждый обратный вызов выполняется по порядку. Если вы нажмете первую кнопку, usekeyUp связывает keyUp. Нажатие Пробел выполняет keyUp, отключает keyUp2 и keyUp3 и предупреждает "hello world". Это не отменяет привязку keyUp.

Если вы затем нажмете другую кнопку, например второй - дополнительно связывает keyUp2. Но если вы нажмете Пробел , прослушиватели событий, которые в настоящее время связаны, по порядку, будут keyUp и keyUp2. Сначала выполняется keyUp, отвязка keyUp2 и keyUp3. Теперь никакой другой прослушиватель событий не привязан, но keyUp остается привязанным навсегда.

Есть примечание об этом поведении в документации :

Если EventListener удаляется из EventTarget во время обработки события, он не будет запускаться текущими действиями. EventListener не будет вызываться для события, для которого он был зарегистрирован после удаления. Однако его можно снова прикрепить.

Итак, removeEventListener «работают», но правильные никогда не достигаются.

Если вы хотите продолжать использовать removeEventListener, переместите строки removeEventListener в соответствующие события click, а не в события keyup.

Встроенные обработчики событий, такие как onclick, не рекомендуются. Это устаревший, сложный в обслуживании и не интуитивно понятный способ регистрации событий. Всегда используйте {{X1} } вместо этого.

document.getElementById("click1").addEventListener("click", function(){
  document.addEventListener("keyup", keyUp1);
  document.removeEventListener("keyup", keyUp2);
  document.removeEventListener("keyup", keyUp3);
});
document.getElementById("click2").addEventListener("click", function(){
  document.removeEventListener("keyup", keyUp1);
  document.addEventListener("keyup", keyUp2);
  document.removeEventListener("keyup", keyUp3);
});
document.getElementById("click3").addEventListener("click", function(){
  document.removeEventListener("keyup", keyUp1);
  document.removeEventListener("keyup", keyUp2);
  document.addEventListener("keyup", keyUp3);
});

function keyUp1(event){
  if (event.code === "Space") {
    alert("hello world")
  }
}

function keyUp2(event){
  if (event.code === "Space") {
    alert("hello")
  }
}

function keyUp3(event){
  if (event.code === "Space") {
    alert("hello3")
  }
}
<input id="click1" type="button" value="First"/>
<input id="click2" type="button" value="Second"/>
<input id="click3" type="button" value="Third"/>

Поскольку этот код довольно WET, лучшим подходом было бы используйте делегирование событий вместо назначения нескольких событий - он более удобен в обслуживании и применяется к динамически добавляемым элементам. Например, используйте аргумент события. target. См. информацию о теге и Что такое делегирование событий DOM?.

{
  let currentAlert;

  addEventListener("keyup", ({code}) => {
    if (currentAlert && code === "Space") {
      alert(currentAlert);
    }
  });

  addEventListener("click", ({target}) => {
    if(target?.dataset?.alert){
      currentAlert = target.dataset.alert;
    }
  });
}
<input data-alert="hello world" type="button" value="First" />
<input data-alert="hello" type="button" value="Second" />
<input data-alert="hello3" type="button" value="Third" />
2
Sebastian Simon 10 Апр 2021 в 07:33