Я хочу использовать событие keyDown для div в React. Я делаю:
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>
)
}
Работает нормально, но хотелось бы больше в стиле React. Я старался
onKeyDown={this.onKeyPressed}
на компоненте. Но не реагирует. Насколько я помню, он работает с элементами ввода.
Как я могу это сделать?
Ответы:
Вы должны использовать атрибут tabIndex, чтобы иметь возможность прослушивать
onKeyDown
событие в div в React. НастройкаtabIndex="0"
должна запустить ваш обработчик.источник
tabIndex={-1}
также может использоваться, если вы работаете с элементом, который не является интерактивным, и не хотите изменять порядок табуляции в документе.Вам нужно написать это так
<div className="player" style={{ position: "absolute" }} onKeyDown={this.onKeyPressed} tabIndex="0" >
Если
onKeyPressed
не привязанthis
, попробуйте переписать его с помощью стрелочной функции или привязать к компонентуconstructor
.источник
console.log
ничего не выводит?Вы слишком много думаете на чистом Javascript. Избавьтесь от слушателей этих методов жизненного цикла React и используйте
event.key
вместо нихevent.keyCode
(потому что это не объект события JS, это React SyntheticEvent ). Весь ваш компонент может быть таким же простым (при условии, что вы не связали свои методы в конструкторе).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> ) }
источник
event
объект - React SyntheticEvent .onClick
опорой вместоonKeyDown
срабатывания обработчика.Ответ с
<div className="player" onKeyDown={this.onKeyPressed} tabIndex={0} >
у меня работает, обратите внимание, что tabIndex требует числа, а не строки, поэтому tabIndex = "0" не работает.
источник
Использование
div
трюка сtab_index="0"
илиtabIndex="-1"
работает, но каждый раз, когда пользователь фокусирует внимание на представлении, которое не является элементом, вы получаете уродливую схему фокуса на всем веб-сайте. Это можно исправить, установив CSS для div, который будет использоватьсяoutline: none
в фокусе.Вот реализация со стилизованными компонентами:
import styled from "styled-components" const KeyReceiver = styled.div` &:focus { outline: none; } `
и в классе App:
render() { return ( <KeyReceiver onKeyDown={this.handleKeyPress} tabIndex={-1}> Display stuff... </KeyReceiver> )
источник
Вам не хватает привязки метода в конструкторе. Вот как React предлагает вам это сделать:
class Whatever { constructor() { super(); this.onKeyPressed = this.onKeyPressed.bind(this); } onKeyPressed(e) { // your code ... } render() { return (<div onKeyDown={this.onKeyPressed} />); } }
Есть и другие способы сделать это, но во время выполнения это будет наиболее эффективным.
источник
Вы должны предотвратить запуск события по умолчанию.
onKeyPressed(e) { e.preventDefault(); console.log(e.key); }
источник