模式中的香草javascript陷阱焦点(可访问性选项卡)

模式中的香草javascript陷阱焦点(可访问性选项卡),javascript,focus,accessibility,tabbing,Javascript,Focus,Accessibility,Tabbing,这应该很简单,但由于某些原因它不起作用,我在正确的时间获得了正确的console.logs,但是焦点不在正确的位置,请参考我的JSFIDLE 问题之一是您使用的是keyup而不是keydown。键控仅在选项卡已触发后才会触发。但是,更改代码会导致键盘被困在其中一个链接上。代码有缺陷 下面是一些实现您所需功能的代码(使用jQuery) 您可以在此处看到此对话框的工作版本 单击其中一个彩色框中的文本以查看弹出的对话框。默认的e.preventDefault()对keyup事件没有影响(因为默认

这应该很简单,但由于某些原因它不起作用,我在正确的时间获得了正确的console.logs,但是焦点不在正确的位置,请参考我的JSFIDLE


问题之一是您使用的是
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'))