我正在尝试为可访问性制作键盘导航焦点大纲。伪 :focus-visible
类适用于除输入之外的所有元素,如文本或文本区域。似乎输入总是会激活这个伪类,因为它需要键盘输入。环顾四周,我找不到修复它的方法,因此它的行为与所有其他可交互元素一样。所以我想我只是在渲染时通过 onFocus 对其进行排序,通过显示/隐藏将根据用户如何聚焦输入而出现和消失的自定义 css 类。
我已经设法做到了,但问题是我不知道现在如何进一步区分输入来自键盘还是鼠标。这是我到目前为止所得到的。第一反应钩子:
const [keyboardFocus, setKeyboardFocus] = useState(false);
const toggleKeyboardFocusOn = () => setKeyboardFocus(true);
const toggleKeyboardFocusOff = () => setKeyboardFocus(false);
所以我们有他们的keyboardFocus钩子,并切换onFocus和onBlur,它们应该定义天气输入是否应该有键盘焦点。然后我有类选择器来确定键盘仅大纲是否处于活动状态:
const inputClassNames = classNames({
...
[css.keyboardOnlyFocus]: keyboardFocus,
});
最后在输入的渲染中我有
onBlur={toggleKeyboardFocusOff}
onFocus={toggleKeyboardFocusOn}
到此为止,专注于工作,会显示大纲。我遇到的问题是我现在如何在 onFocus 中确定事件是否来自鼠标,在这种情况下它应该被忽略还是来自键盘。
我尝试过的解决方案之一是这样的:
onFocus={(e) => ({
if(e.key === 'Tab') {
toggleKeyboardFocusOn;
}
})
然而什么也没发生,e.key 的控制台输出显示为未定义。那么,告诉 onFocus 事件是来自鼠标还是键盘的正确方法是什么?
答案 0 :(得分:0)
我认为您最好的机会是找出鼠标点击事件和焦点事件发生的顺序,以及它们是否同步(发生在同一个 event loop 期间)
这里有一些代码可以帮助您入门:
const eventObserved = useRef(false);
const checkOther = () => {
if (eventObserved.current) {
console.log('synchronous!');
} else {
eventObserved.current = true;
setTimeout(() => { eventObserved.current = false });
}
};
return (
<input
onClick={() => {
console.log('clicked');
checkOther();
}}
onFocus={() => {
console.log('focus');
checkOther();
}}
/>
);
您也可以考虑将 MouseDown 和 MouseUp 与单击分开处理。也许您需要深入到裸机并使用本机事件而不是反应合成事件。