这应该很简单但是由于某些原因它不起作用,我在正确的时间获得了正确的console.logs,但重点是没有到达正确的位置,请参考我的jsfiddle
https://jsfiddle.net/bqt0np9d/
function checkTabPress(e) {
"use strict";
// pick passed event of global event object
e = e || event;
if (e.keyCode === 9) {
if (e.shiftKey) {
console.log('back tab pressed');
firstItem.onblur=function(){
console.log('last a focus left');
lastItem.focus();
};
e.preventDefault();
}
console.log('tab pressed');
lastItem.onblur=function(){
console.log('last a focus left');
firstItem.focus();
};
e.preventDefault();
}
}
modal.addEventListener('keyup', checkTabPress);
答案 0 :(得分:1)
我必须将焦点锁定在我们在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]();
}
}
}
答案 1 :(得分:0)
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>
那是因为在这种情况下没有默认的浏览器操作,然后没有要防止的操作。
答案 2 :(得分:0)
很难将焦点放在模态中是靠自己完成的。如果您能够在项目中安装第三方依赖项,则可以使用focus-trap软件包。
您可以使用原始Javascript轻松地将焦点吸引到任何组件上;
import { createFocusTrap } from 'focus-trap'
const modal = document.getElementById('modal')
const focusTrap = createFocusTrap('#modal', {
onActivate: function () {
modal.className = 'trap is-visible'
},
onDeactivate: function () {
modal.className = 'trap'
},
})
document.getElementById('show').addEventListener('click', function () {
focusTrap.activate()
})
document.getElementById('hide').addEventListener('click', function () {
focusTrap.deactivate()
})
甚至是React;
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'))
我做了一个关于软件包here的小写,它解释了如何将其与原始Javascript或React结合使用。