onKeyDown 事件不适用于 React 中的 div

onKeyDown event not working on divs in React

我想在 React 中的 div 上使用 keyDown 事件。我愿意:

  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}

在组件上。但它没有反应。我记得它适用于输入元素。

Codepen

我该怎么做?

你需要这样写

<div 
    className="player"
    style={{ position: "absolute" }}
    onKeyDown={this.onKeyPressed}
    tabIndex="0"
  >

如果onKeyPressed没有绑定到this,那么尝试用箭头函数重写或者在组件constructor.

中绑定

你想得太多了 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>
  )
}

您应该使用 tabIndex 属性,以便能够在 React 中侦听 div 上的 onKeyDown 事件。设置 tabIndex="0" 应该会触发您的处理程序。

答案与

<div 
    className="player"
    onKeyDown={this.onKeyPressed}
    tabIndex={0}
>

对我有用,请注意 tabIndex 需要一个数字,而不是字符串,所以 tabIndex="0" 不起作用。

div 技巧与 tab_index="0"tabIndex="-1" 一起使用是可行的,但任何时候用户关注的视图不是元素时,你都会得到一个丑陋的 focus-outline在整个网站上。这可以通过将 div 的 CSS 设置为在焦点中使用 outline: none 来解决。

这是带有样式组件的实现:

import styled from "styled-components"

const KeyReceiver = styled.div`
  &:focus {
    outline: none;
  }
`

在应用程序中 class:

  render() {
    return (      
      <KeyReceiver onKeyDown={this.handleKeyPress} tabIndex={-1}>
          Display stuff...
      </KeyReceiver>
    )

此外,请记住,只有当焦点设置在您的 div 上时,此技巧才会起作用。如果你想在 div 弹出时立即管理按键,你可以使用 this trick (对 Drawers/Modals 特别有用)