在 React 中使用键盘的 up/down 箭头键滚动?
Scroll with keyboard's up/down arrows keys in React?
我有一个自定义列表框,一个 div
包含其他 div
children 的垂直列表。我想添加一个 up/down 箭头键导航来更改 child 当前 selected.
因此,当我单击第一项并按 down arrow key
时,它应该允许我 select 第二项(下一项)。如果我单击 up arrow key
,它应该 select 返回第一项(上一项)。
const renderInboxSummary = targetDetailsData.map((todo, index) => {
const hasNewMessageInd = todo.hasNewMessageInd;
return (
<div onClick={() => this.handleClick(targetDetailsData, todo.aprReference, index)}>
<div>
{todo.aprRecordUserName}
</div>
<div>
{todo.aprBranchCode}
</div>
<div>
{todo.aprScreeName}
</div>
</div>
);
});
每个 div
都有一个点击事件处理程序 this.handleClick(targetDetailsData, todo.aprReference, index)
。
这可以通过在 ReactJS 中使用 ref
然后为 keydown
事件添加事件侦听器然后将焦点移动到下一个或上一个兄弟来完成。
备注
- 我为每个 div 添加了
tabindex
属性,让它们成为焦点
- 我在包装元素上使用
ref
来监听 keydown
- 我检查
keycode
是否 up/down 移动到 next/previous 兄弟姐妹
- 我相信全尺寸键盘上 up/down 的
keycode
是不同的,但我没有要测试的。
解决方案
要测试演示,请单击任意 div,然后使用 up/down 箭头
const { Component } = React;
class App extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
this.moveFocus();
}
moveFocus() {
const node = this.myRef.current;
node.addEventListener('keydown', function(e) {
const active = document.activeElement;
if(e.keyCode === 40 && active.nextSibling) {
active.nextSibling.focus();
}
if(e.keyCode === 38 && active.previousSibling) {
active.previousSibling.focus();
}
});
}
render() {
return (
<div ref={this.myRef}>
<div tabindex="0">First</div>
<div tabindex="1">Second</div>
<div tabindex="2">Third</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
div:focus {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
文档
https://reactjs.org/docs/refs-and-the-dom.html
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
我有一个自定义列表框,一个 div
包含其他 div
children 的垂直列表。我想添加一个 up/down 箭头键导航来更改 child 当前 selected.
因此,当我单击第一项并按 down arrow key
时,它应该允许我 select 第二项(下一项)。如果我单击 up arrow key
,它应该 select 返回第一项(上一项)。
const renderInboxSummary = targetDetailsData.map((todo, index) => {
const hasNewMessageInd = todo.hasNewMessageInd;
return (
<div onClick={() => this.handleClick(targetDetailsData, todo.aprReference, index)}>
<div>
{todo.aprRecordUserName}
</div>
<div>
{todo.aprBranchCode}
</div>
<div>
{todo.aprScreeName}
</div>
</div>
);
});
每个 div
都有一个点击事件处理程序 this.handleClick(targetDetailsData, todo.aprReference, index)
。
这可以通过在 ReactJS 中使用 ref
然后为 keydown
事件添加事件侦听器然后将焦点移动到下一个或上一个兄弟来完成。
备注
- 我为每个 div 添加了
tabindex
属性,让它们成为焦点 - 我在包装元素上使用
ref
来监听keydown
- 我检查
keycode
是否 up/down 移动到 next/previous 兄弟姐妹 - 我相信全尺寸键盘上 up/down 的
keycode
是不同的,但我没有要测试的。
解决方案
要测试演示,请单击任意 div,然后使用 up/down 箭头
const { Component } = React;
class App extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
this.moveFocus();
}
moveFocus() {
const node = this.myRef.current;
node.addEventListener('keydown', function(e) {
const active = document.activeElement;
if(e.keyCode === 40 && active.nextSibling) {
active.nextSibling.focus();
}
if(e.keyCode === 38 && active.previousSibling) {
active.previousSibling.focus();
}
});
}
render() {
return (
<div ref={this.myRef}>
<div tabindex="0">First</div>
<div tabindex="1">Second</div>
<div tabindex="2">Third</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
div:focus {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
文档
https://reactjs.org/docs/refs-and-the-dom.html
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex