在 React 中关注 div 而无需点击以在模块上启用键盘导航
Focus on div without click in React to enable keyboard navigation on a module
我在 React 中从头开始编写图片库,当单击图片时,会弹出一个模式(与我的图库组件分开的组件)。我想 使用左右箭头 在图片之间导航,而不仅仅是使用屏幕上添加的箭头 (onclick),但目前它只在我单击时关注模式一次,然后我也可以使用键盘导航 (onKeyDown)。
我已将 tabIndex="0" 添加到我的 div,但我仍然需要单击 div 一次才能关注它。
<div tabIndex="0" onKeyDown={(event) => this.onKeyNavigation(event, ImageUrl, currentIndex, ImageUrls)}>
onKeyNavigation = (event, ImageUrl, currentIndex, ImageUrls) => {
if ((event.keyCode) === 39) {
this.props.loadNext(ImageUrl, currentIndex, ImageUrls)
}
else if ((event.keyCode) === 37) {
this.props.loadPrevious(ImageUrl, currentIndex, ImageUrls)
}
else if ((event.keyCode) === 27) {
this.props.onClose()
}
}
您需要在 <div>
上触发一个 focus()
事件,以便在呈现后获得焦点。
最简单的方法是使用 React 的内置生命周期方法。首先,为您想要获得焦点的元素创建一个 ref(在本例中,div 监听 keyDown 事件)。然后,您可以在组件的 componentDidMount()
方法中对该节点调用 focus()
:
class ImageGallery extends React.Component {
construtor(){
super();
// Create the ref in the constructor
this.focusRef = React.createRef();
}
/* your other methods here */
componentDidMount(){
// Focus on the rendered div using the DOM focus() method
this.focusRef.focus();
}
render(){
// Set the ref in your render() method
return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
}
}
所以解决方案是:
componentDidUpdate(){
this.focusRef.current.focus();
}
dcastrodale 你的回答对我帮助很大,但出于某种原因,直到我将 ref 放在 setTimeout() 内的 componentDidMount() 中,这才行得通。这是我在页面加载时专注于特定 div 所做的。
//This line was added in the constructor().
this.drumMachineAndOuterControllerRef = React.createRef();
//This is how my componentDidMount() looks like.
componentDidMount() {
setTimeout(() => {
this.drumMachineAndOuterControllerRef.current.focus();
}, 5);
}
//This is the div that is put in focus after the page loads.
<div id="drum-machine-and-outer-controller" tabIndex="0" onKeyDown={this.keyboardPress} ref={this.drumMachineAndOuterControllerRef}>
这对我来说非常有用,我什至可以在鼠标指针不进入浏览器的情况下使用键盘按下按钮元素 window。
再次感谢 dcastrodale!你的回答指引了我正确的方向。
我在 React 中从头开始编写图片库,当单击图片时,会弹出一个模式(与我的图库组件分开的组件)。我想 使用左右箭头 在图片之间导航,而不仅仅是使用屏幕上添加的箭头 (onclick),但目前它只在我单击时关注模式一次,然后我也可以使用键盘导航 (onKeyDown)。
我已将 tabIndex="0" 添加到我的 div,但我仍然需要单击 div 一次才能关注它。
<div tabIndex="0" onKeyDown={(event) => this.onKeyNavigation(event, ImageUrl, currentIndex, ImageUrls)}>
onKeyNavigation = (event, ImageUrl, currentIndex, ImageUrls) => {
if ((event.keyCode) === 39) {
this.props.loadNext(ImageUrl, currentIndex, ImageUrls)
}
else if ((event.keyCode) === 37) {
this.props.loadPrevious(ImageUrl, currentIndex, ImageUrls)
}
else if ((event.keyCode) === 27) {
this.props.onClose()
}
}
您需要在 <div>
上触发一个 focus()
事件,以便在呈现后获得焦点。
最简单的方法是使用 React 的内置生命周期方法。首先,为您想要获得焦点的元素创建一个 ref(在本例中,div 监听 keyDown 事件)。然后,您可以在组件的 componentDidMount()
方法中对该节点调用 focus()
:
class ImageGallery extends React.Component {
construtor(){
super();
// Create the ref in the constructor
this.focusRef = React.createRef();
}
/* your other methods here */
componentDidMount(){
// Focus on the rendered div using the DOM focus() method
this.focusRef.focus();
}
render(){
// Set the ref in your render() method
return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
}
}
所以解决方案是:
componentDidUpdate(){
this.focusRef.current.focus();
}
dcastrodale 你的回答对我帮助很大,但出于某种原因,直到我将 ref 放在 setTimeout() 内的 componentDidMount() 中,这才行得通。这是我在页面加载时专注于特定 div 所做的。
//This line was added in the constructor().
this.drumMachineAndOuterControllerRef = React.createRef();
//This is how my componentDidMount() looks like.
componentDidMount() {
setTimeout(() => {
this.drumMachineAndOuterControllerRef.current.focus();
}, 5);
}
//This is the div that is put in focus after the page loads.
<div id="drum-machine-and-outer-controller" tabIndex="0" onKeyDown={this.keyboardPress} ref={this.drumMachineAndOuterControllerRef}>
这对我来说非常有用,我什至可以在鼠标指针不进入浏览器的情况下使用键盘按下按钮元素 window。
再次感谢 dcastrodale!你的回答指引了我正确的方向。