Lo que espero que haga mi código Cuando hago clic en el primer botón y luego presiono la tecla Espacio, debería alertar "hola mundo". Cuando hago clic en el segundo botón y luego presiono la tecla Espacio, espero que ...

0
coder 10 abr. 2021 a las 09:39

1 respuesta

La mejor respuesta

Actualmente, cuando presiona Espacio , todos los detectores de eventos todavía están vinculados (desde los clics del botón) y cada devolución de llamada se ejecuta en orden. Si presiona el primer botón, usekeyUp enlaza keyUp. Presionar Espacio ejecuta keyUp, desvincula keyUp2 y keyUp3 y alerta "hello world". no desvincula keyUp.

Si luego hace clic en un botón diferente, p. Ej. el segundo, adicionalmente vincula keyUp2. Pero si presiona Espacio , los oyentes de eventos que están enlazados actualmente, en orden, son keyUp y keyUp2. Primero, keyUp se ejecuta, desvinculando keyUp2 y keyUp3. Ahora, ningún otro detector de eventos está vinculado, pero keyUp permanece vinculado , para siempre.

Hay una nota sobre este comportamiento en la documentación :

Si un EventListener se elimina de un EventTarget mientras está procesando un evento, las acciones actuales no lo activarán. No se invocará un EventListener para el evento para el que se registró después de ser eliminado. Sin embargo, se puede volver a colocar.

Entonces, los removeEventListener s “funcionan”, pero nunca se alcanzan los correctos.

Si desea seguir usando removeEventListener, mueva las líneas removeEventListener a los eventos click respectivos, no a los eventos keyup.

Los controladores de eventos integrados como onclick no se recomiendan. Son una forma obsoleta, difícil de mantener y poco intuitiva de registrar eventos. Siempre use {{X1} } en su lugar.

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"/>

Dado que este código es bastante WET, un mejor enfoque sería use delegación de eventos en lugar de asignar varios eventos - es más fácil de mantener y se aplica a elementos agregados dinámicamente. Por ejemplo, use un argumento de evento target. Consulte la información de la etiqueta y ¿Qué es la delegación de eventos 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 abr. 2021 a las 07:33