在非输入元素上执行onKeyDown / onKeyUp事件

时间:2016-08-25 02:45:50

标签: events reactjs setstate

我需要捕获cmd按钮上下事件,以便选择是否在setState中使用串联。我如何在表格元素上获得这些事件?

2 个答案:

答案 0 :(得分:4)

您必须在身体/窗口级别捕获按键。表元素没有输入焦点,因此您无法从表中捕获键(没有输入元素)。

var cmdDown = false;

document.body.addEventListener('keydown', function(event) {
  var key = event.keyCode || event.charCode || 0;
  if ([91,93,224,17].indexOf(key) !== -1) {
    cmdDown = true;
  }
  console.log('CMD DOWN: ' + cmdDown.toString());    
});

document.body.addEventListener('keyup', function(event) {
  var key = event.keyCode || event.charCode || 0;
  if ([91,93,224,17].indexOf(key) !== -1) {
    cmdDown = false;
  }
  console.log('CMD DOWN: ' + cmdDown.toString());
});

答案 1 :(得分:0)

简单示例

我相信这里的最佳做法是向 document 添加一个事件侦听器并相应地修改您的元素(例如表格)。使用完整的 React 组件扩展 u/Hardy 的答案:

class MyComponent extends React.Component {

  // Using an arrow function. Alternatively, could bind() this 
  // function in the component's constructor
  keydownHandler = (event) => {
    // Add logic, e.x. check event.keyCode to see 
    // if CMD is pressed and then update state
  }

  componentDidMount() {
    document.addEventListener("keydown", this.keydownHandler);
  }

  componentWillUnmount() {
    this.removeEventListener("keydown", this.keydownHandler);
  }

  render() {
    <div>Hello World</div>
  }
}

替代方案

作为 others have noted,使用绑定到非输入元素的键盘事件存在挑战,因为浏览器需要这些元素处于焦点才能调用绑定回调。另一种似乎有效的方法是设置组件的 tabindex 属性以使元素成为焦点。来自u/burak's answer

render() {
  <div onKeyDown={this.keydownHandler} tabindex={-1}>Example</div>
}

这具有连接到 React's Synthetic Events 的好处,即“浏览器原生事件的跨浏览器包装器”。但是,在修改 tabindex 属性时,请务必注意这可能会改变可聚焦元素的顺序,并影响用户使用键盘或辅助功能软件浏览您网站的能力。一些用户报告说,将 tabindex 设置为 -1 可以解决此问题(请参阅上一个链接中的评论)。