模式中的香草javascript陷阱焦点(可访问性选项卡)
这应该很简单,但由于某些原因它不起作用,我在正确的时间获得了正确的console.logs,但是焦点不在正确的位置,请参考我的JSFIDLE模式中的香草javascript陷阱焦点(可访问性选项卡),javascript,focus,accessibility,tabbing,Javascript,Focus,Accessibility,Tabbing,这应该很简单,但由于某些原因它不起作用,我在正确的时间获得了正确的console.logs,但是焦点不在正确的位置,请参考我的JSFIDLE 问题之一是您使用的是keyup而不是keydown。键控仅在选项卡已触发后才会触发。但是,更改代码会导致键盘被困在其中一个链接上。代码有缺陷 下面是一些实现您所需功能的代码(使用jQuery) 您可以在此处看到此对话框的工作版本 单击其中一个彩色框中的文本以查看弹出的对话框。默认的e.preventDefault()对keyup事件没有影响(因为默认
问题之一是您使用的是
keyup
而不是keydown
。键控仅在选项卡已触发后才会触发。但是,更改代码会导致键盘被困在其中一个链接上。代码有缺陷
下面是一些实现您所需功能的代码(使用jQuery)
您可以在此处看到此对话框的工作版本
单击其中一个彩色框中的文本以查看弹出的对话框。默认的
e.preventDefault()
对keyup
事件没有影响(因为默认浏览器操作已经启动)
尽管如此,您的示例仍然有效。但只有在模式前后都有链接时
如果您使用以下内容更改HTML代码,请在模式前添加一个链接,在模式后添加一个链接;您将看到您的焦点被困在模态中:
<a href="#">other link</a>
<div id="modal">
<a href="#">Link One</a>
<a href="#">Link Two</a>
</div>
<a href="#">other link</a>
这是因为在这种情况下,没有默认的浏览器操作,也没有要阻止的操作。我必须在React组件中使用的模式内锁定焦点。 我为“向下键”和“收集”选项卡以及Shift+选项卡添加了eventListner
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]();
}
}
}
在一个模态中捕获焦点是非常困难的。如果能够在项目中安装第三方依赖项,则可以使用该软件包 您可以使用普通Javascript轻松地将焦点捕获到任何组件
从“焦点陷阱”导入{createFocusTrap}
const modal=document.getElementById('modal')
const focusTrap=createFocusTrap(“#model”{
onActivate:function(){
modal.className='陷阱可见'
},
onDeactivate:函数(){
modal.className='trap'
},
})
document.getElementById('show').addEventListener('click',function(){
focusTrap.activate()
})
document.getElementById('hide').addEventListener('click',function(){
focusTrap.deactivate()
})
甚至反应
import React from 'react'
import ReactDOM from 'react-dom'
// Use the wrapper package of `focus-trap` to use with React.
import FocusTrap from 'focus-trap-react'
const Demo = () => {
const [showModal, setShowModal] = React.useState(false)
return (
<div>
<button onClick={() => setShowModal(true)}>show modal</button>
<FocusTrap active={showModal}>
<div id="modal">
Modal with <a href="#">with</a> <a href="#">some</a>{' '}
<a href="#">focusable</a> elements.
<button onClick={() => setShowModal(false)}>
hide modal
</button>
</div>
</FocusTrap>
</div>
)
}
ReactDOM.render(<Demo />, document.getElementById('demo'))
从“React”导入React
从“react dom”导入react dom
//使用'focustrap'的包装包与React一起使用。
从“焦点陷阱反应”导入焦点陷阱
常量演示=()=>{
const[showmodel,setshowmodel]=React.useState(false)
返回(
设置显示模式(真)}>显示模式
带{'}的模态
元素。
setShowModal(假)}>
隐藏模态
)
}
ReactDOM.render(,document.getElementById('demo'))
我写了一篇关于这个包的小文章,解释了如何将它与vanilla Javascript或React一起使用。谢谢,不过我已经将它与jQuery一起使用了。对于我正在进行的项目,我需要使用纯javascript。关于如何修改当前代码以使其正常工作,有什么想法吗?
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]();
}
}
}
import React from 'react'
import ReactDOM from 'react-dom'
// Use the wrapper package of `focus-trap` to use with React.
import FocusTrap from 'focus-trap-react'
const Demo = () => {
const [showModal, setShowModal] = React.useState(false)
return (
<div>
<button onClick={() => setShowModal(true)}>show modal</button>
<FocusTrap active={showModal}>
<div id="modal">
Modal with <a href="#">with</a> <a href="#">some</a>{' '}
<a href="#">focusable</a> elements.
<button onClick={() => setShowModal(false)}>
hide modal
</button>
</div>
</FocusTrap>
</div>
)
}
ReactDOM.render(<Demo />, document.getElementById('demo'))