onKeyDown事件不在React中的div上工作

Mic*_*ael 70 events keypress keydown reactjs

我想在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>
    )
  }
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我想在React风格中做得更多.我试过了

        onKeyDown={this.onKeyPressed}
Run Code Online (Sandbox Code Playgroud)

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

Codepen:http://codepen.io/lafisrap/pen/OmyBYG

我该怎么做?

bur*_*kan 114

您应该使用tabIndex属性来在React中侦听div上的onKeyDown事件.设置tabIndex ="0"应该激活你的处理程序.

  • 如果您正在使用非交互式元素并且不想更改文档的 Tab 键顺序,也可以使用“tabIndex={-1}”。 (20认同)
  • 这似乎是糟糕的、固执己见的设计。如果我想处理容器元素上的冒泡事件,但该容器本身不应该获得焦点,该怎么办? (3认同)

Pan*_*her 14

你需要这样写

<div 
    className="player"
    style={{ position: "absolute" }}
    onKeyDown={this.onKeyPressed}
    tabIndex="0"
  >
Run Code Online (Sandbox Code Playgroud)

如果onKeyPressed未绑定this,则尝试使用箭头函数重写它或将其绑定到组件中constructor.

  • 对不起。我敢肯定,我只是忽略了这一点。但这不是问题。它仍然无法正常工作。 (2认同)

Mup*_*pet 10

使用或 的div技巧是有效的,但是每当用户将焦点集中在不是元素的视图上时,您就会在整个网站上看到丑陋的焦点轮廓。可以通过设置要在焦点中使用的 div 的 CSS 来解决此问题。tab_index="0"tabIndex="-1"outline: none

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

import styled from "styled-components"

const KeyReceiver = styled.div`
  &:focus {
    outline: none;
  }
`
Run Code Online (Sandbox Code Playgroud)

在 App 类中:

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


ste*_*eel 9

你在纯 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>
  )
}
Run Code Online (Sandbox Code Playgroud)


Pie*_*ran 7

另外,请记住,此技巧仅在焦点位于 div 上时才有效。如果你想在 div 弹出后立即管理按键,你可以使用这个技巧(对于 Drawers/Modals 特别有用)