我已经建立了自己的反应模式。当我打开模态时按Tab键,焦点仍然会转到背景页面。如何限制模态内组件的焦点?
下面的逻辑应该是什么?
onKeyPress (e) {
if (e.keyCode === 9) {
e.preventDefault();
// logic here?
}
}
反应模态代码:
<ReactModal onKeyPress={this.onKeyPress} >
<input type="text"/>
<input type="text"/>
</ReactModal>
答案 0 :(得分:3)
嗯,你可以使用聚焦陷阱来做到这一点。请查看此npm module。只需将包含模态的内容包裹在这样的焦点陷阱中。
<FocusTrap
focusTrapOptions={{
...
}}
>
<div className="trap">
<p>
Here is a focus trap
{' '}
<a href="#">with</a>
{' '}
<a href="#">some</a>
{' '}
<a href="#">focusable</a>
{' '}
parts.
</p>
<p>
<button onClick={this.someCallback}>
Click Me
</button>
</p>
</div>
</FocusTrap>
我建议你不要自己实现它,而不是给你实现这个的建议。考虑到可访问性很难做到正确。
相反,我建议您使用可访问的现成模态组件,例如react-modal。它是完全可定制的,您可以在其中放置任何您想要的内容,但它可以正确处理可访问性,以便盲人仍然可以使用您的模态。
答案 1 :(得分:0)
我必须将焦点锁定在我们在React组件中使用的模式中。我添加了用于DOWN的eventListner并收集了Tab和Shift + Tab
class Modal extends Component {
componentDidMount() {
window.addEventListener("keyup", this.handleKeyUp, false);
window.addEventListener("keydown", this.handleKeyDown, false);
}
componentWillUnmount() {
window.removeEventListener("keyup", this.handleKeyUp, false);
window.removeEventListener("keydown", this.handleKeyDown, false);
}
handleKeyDown = (e) => {
//Fetch node list from which required elements could be grabbed as needed.
const modal = document.getElementById("modal_parent");
const tags = [...modal.querySelectorAll('select, input, textarea, button, a, li')].filter(e1 => window.getComputedStyle(e1).getPropertyValue('display') === 'block');
const focusable = modal.querySelectorAll('button, [href], input, select, textarea, li, a,[tabindex]:not([tabindex="-1"])');
const firstFocusable = focusable[0];
const lastFocusable = focusable[focusable.length - 1];
if (e.ctrlKey || e.altKey) {
return;
}
const keys = {
9: () => { //9 = TAB
if (e.shiftKey && e.target === firstFocusable) {
lastFocusable.focus();
}
if (e.target === lastFocusable) {
firstFocusable.focus();
}
}
};
if (keys[e.keyCode]) {
keys[e.keyCode]();
}
}
}