如何检测 React 应用程序页面上任何位置的按键?
How to detect keydown anywhere on page in a React app?
我正在尝试检测使用 React 构建的应用程序页面上任意位置的按键操作。
我记得在 jQuery 中这很容易,但我想看看是否可以在 React 中完成。我不想做一个 'frankenstein' 项目,即有些部分在反应中,有些部分在 jQuery 中,如果完全可以避免的话。
到目前为止我有:
export default function App() {
const handleKeyPress = (event) => {
console.log(event.keyCode);
}
return (
<div
onKeyDown={handleKeyPress}
tabIndex="0"
>
<Header page_num={100}/>
</div>
);
}
但它似乎只有在用户单击页面中的实际 div,然后按下某个键时才会起作用。
我希望无需用户单击页面上的任何地方即可检测按键。
您可以使用 useEffect
钩子来实现这一点,并向 document
添加一个事件监听器:
import React, { useEffect } from "react";
export default ({ name }) => {
useEffect(() => {
function handleKeyDown(e) {
console.log(e.keyCode);
}
document.addEventListener('keydown', handleKeyDown);
// Don't forget to clean up
return function cleanup() {
document.removeEventListener('keydown', handleKeyDown);
}
}, []);
return <div>Keydown</div>;
};
这是一个 example 的动作。
假设 <div>
通过 tabindex
或类似的方式获得焦点,您将能够在按键处理程序中看到 e.target
将是 <div>
。您还可以将功能包装在另一个组件中,并在它的 keydown 处理程序中检查 keydown 是否在该元素上执行,而不是使用 contains.
在外部执行
这是另一个 example,它使用 contains
检查事件目标是否在 div ref
:
import React, { useEffect, useRef } from "react";
function Hello({ onKeyDown }) {
const ref = useRef();
useEffect(() => {
function handleKeyDown(e) {
// check if keydown was contained in target div
if (!ref.current || ref.current.contains(event.target)) {
return;
}
// Emit event to parent component
onKeyDown(e);
}
document.addEventListener("keydown", handleKeyDown);
return function cleanup() {
document.removeEventListener("keydown", handleKeyDown);
};
}, []);
return (
<div ref={ref} tabIndex="0">
foo bar baz
</div>
);
}
export default Hello;
希望对您有所帮助!
我正在尝试检测使用 React 构建的应用程序页面上任意位置的按键操作。
我记得在 jQuery 中这很容易,但我想看看是否可以在 React 中完成。我不想做一个 'frankenstein' 项目,即有些部分在反应中,有些部分在 jQuery 中,如果完全可以避免的话。
到目前为止我有:
export default function App() {
const handleKeyPress = (event) => {
console.log(event.keyCode);
}
return (
<div
onKeyDown={handleKeyPress}
tabIndex="0"
>
<Header page_num={100}/>
</div>
);
}
但它似乎只有在用户单击页面中的实际 div,然后按下某个键时才会起作用。
我希望无需用户单击页面上的任何地方即可检测按键。
您可以使用 useEffect
钩子来实现这一点,并向 document
添加一个事件监听器:
import React, { useEffect } from "react";
export default ({ name }) => {
useEffect(() => {
function handleKeyDown(e) {
console.log(e.keyCode);
}
document.addEventListener('keydown', handleKeyDown);
// Don't forget to clean up
return function cleanup() {
document.removeEventListener('keydown', handleKeyDown);
}
}, []);
return <div>Keydown</div>;
};
这是一个 example 的动作。
假设 <div>
通过 tabindex
或类似的方式获得焦点,您将能够在按键处理程序中看到 e.target
将是 <div>
。您还可以将功能包装在另一个组件中,并在它的 keydown 处理程序中检查 keydown 是否在该元素上执行,而不是使用 contains.
这是另一个 example,它使用 contains
检查事件目标是否在 div ref
:
import React, { useEffect, useRef } from "react";
function Hello({ onKeyDown }) {
const ref = useRef();
useEffect(() => {
function handleKeyDown(e) {
// check if keydown was contained in target div
if (!ref.current || ref.current.contains(event.target)) {
return;
}
// Emit event to parent component
onKeyDown(e);
}
document.addEventListener("keydown", handleKeyDown);
return function cleanup() {
document.removeEventListener("keydown", handleKeyDown);
};
}, []);
return (
<div ref={ref} tabIndex="0">
foo bar baz
</div>
);
}
export default Hello;
希望对您有所帮助!