Quiero usar un evento keyDown en un div en React. Hago:
componentWillMount() {
document.addEventListener("keydown", this.onKeyPressed.bind(this));
}
componentWillUnmount() {
document.removeEventListener("keydown", this.onKeyPressed.bind(this));
}
onKeyPressed(e) {
console.log(e.keyCode);
}
render() {
let player = this.props.boards.dungeons[this.props.boards.currentBoard].player;
return (
<div
className="player"
style={{ position: "absolute" }}
onKeyDown={this.onKeyPressed} // not working
>
<div className="light-circle">
<div className="image-wrapper">
<img src={IMG_URL+player.img} />
</div>
</div>
</div>
)
}
Funciona bien, pero me gustaría hacerlo más al estilo React. Lo intenté
onKeyDown={this.onKeyPressed}
en el componente. Pero no reacciona. Funciona en elementos de entrada, según recuerdo.
¿Cómo puedo hacerlo?
Respuestas:
Debe usar el atributo tabIndex para poder escuchar el
onKeyDown
evento en un div en React. La configuracióntabIndex="0"
debería despedir a su manejador.fuente
tabIndex={-1}
también se puede usar si está trabajando con un elemento que no es interactivo y no desea cambiar el orden de tabulación del documento.Necesitas escribirlo de esta manera
<div className="player" style={{ position: "absolute" }} onKeyDown={this.onKeyPressed} tabIndex="0" >
Si
onKeyPressed
no está vinculado athis
, intente reescribirlo usando la función de flecha o vincularlo en el componenteconstructor
.fuente
console.log
no genera nada?Estás pensando demasiado en Javascript puro. Deshágase de sus oyentes en esos métodos de ciclo de vida de React y utilícelos en
event.key
lugar deevent.keyCode
(porque este no es un objeto de evento JS, es un React SyntheticEvent ). Todo su componente podría ser tan simple como esto (suponiendo que no haya vinculado sus métodos en un constructor).onKeyPressed(e) { console.log(e.key); } render() { let player = this.props.boards.dungeons[this.props.boards.currentBoard].player; return ( <div className="player" style={{ position: "absolute" }} onKeyDown={this.onKeyPressed} > <div className="light-circle"> <div className="image-wrapper"> <img src={IMG_URL+player.img} /> </div> </div> </div> ) }
fuente
event
objeto es un React SyntheticEvent .onClick
accesorio en lugar delonKeyDown
controlador se dispara.La respuesta con
<div className="player" onKeyDown={this.onKeyPressed} tabIndex={0} >
funciona para mí, tenga en cuenta que tabIndex requiere un número, no una cadena, por lo que tabIndex = "0" no funciona.
fuente
Usar el
div
truco contab_index="0"
otabIndex="-1"
funciona, pero cada vez que el usuario enfoca una vista que no es un elemento, obtienes un esquema de enfoque feo en todo el sitio web. Esto se puede solucionar configurando el CSS para que el div lo useoutline: none
en el foco.Aquí está la implementación con componentes con estilo:
import styled from "styled-components" const KeyReceiver = styled.div` &:focus { outline: none; } `
y en la clase App:
render() { return ( <KeyReceiver onKeyDown={this.handleKeyPress} tabIndex={-1}> Display stuff... </KeyReceiver> )
fuente
Falta el enlace del método en el constructor. Así es como React sugiere que lo hagas:
class Whatever { constructor() { super(); this.onKeyPressed = this.onKeyPressed.bind(this); } onKeyPressed(e) { // your code ... } render() { return (<div onKeyDown={this.onKeyPressed} />); } }
Hay otras formas de hacer esto, pero esta será la más eficiente en tiempo de ejecución.
fuente
Debe evitar que se active el evento predeterminado.
onKeyPressed(e) { e.preventDefault(); console.log(e.key); }
fuente