Javascript 单击后反应下拉列表可访问性
在当前情况下,此代码起作用,但当用户单击隐藏菜单时,Javascript 单击后反应下拉列表可访问性,javascript,reactjs,drop-down-menu,Javascript,Reactjs,Drop Down Menu,在当前情况下,此代码起作用,但当用户单击隐藏菜单时,useClickOutside也会触发,菜单会关闭并再次打开。。。有没有办法解决这个问题,当点击外部时,它会关闭,但当点击按钮时,它会打开/关闭 const useClickOutside = (ref, handler) => { useEffect(() => { const clickHandler = (event) => { if (!ref.current || re
useClickOutside
也会触发,菜单会关闭并再次打开。。。有没有办法解决这个问题,当点击外部时,它会关闭,但当点击按钮时,它会打开/关闭
const useClickOutside = (ref, handler) => {
useEffect(() => {
const clickHandler = (event) => {
if (!ref.current || ref.current.contains(event.target)) {
return;
}
handler(event);
};
document.addEventListener('mousedown', clickHandler);
return () => {
document.removeEventListener('mousedown', clickHandler);
};
});
};
const Settings = () => {
const ref = useRef();
const [toggle, setToggle] = useState(false);
useClickOutside(ref, () => setToggle(false));
return (
<div className='settings'>
<button onClick={() => setToggle(!toggle)} className='settings__button'>
Menu
</button>
{toggle && (
<div ref={ref} className='settings__panel'>
<Link className='settings__links' to='/user/settings'>
Your Profile
</Link>
<Link className='settings__links' to='/user/settings'>
Todos history
</Link>
<Link className='settings__links' to='/user/settings'>
Settings
</Link>
<Link className='settings__links' value={'Logout'} to='/user/login'>
Logout
</Link>
</div>
)}
</div>
);
};
const useClickOutside=(ref,handler)=>{
useffect(()=>{
常量clickHandler=(事件)=>{
如果(!ref.current | | ref.current.contains(event.target)){
返回;
}
处理者(事件);
};
document.addEventListener('mousedown',clickHandler);
return()=>{
document.removeEventListener('mousedown',clickHandler);
};
});
};
常量设置=()=>{
const ref=useRef();
const[toggle,setToggle]=useState(false);
使用ClickOutside(ref,()=>setToggle(false));
返回(
setToggle(!toggle)}className='settings\uuu按钮'>
菜单
{切换&&(
你的个人资料
待办事项历史
设置
注销
)}
);
};
您可以利用事件。将调用event.stopPropagation()
添加到隐藏菜单的onClick处理程序函数中
<button
onClick={(e) => {
e.stopPropagation();
setToggle(!toggle);
}}
className='settings__button'
>
Menu
</button>
您可以考虑在<代码>上添加<代码> OnBurr < /Cuff>事件。设置< <代码> div,使用<代码> TabeCys= 0 < /P> 然后,您可以捕获div的模糊,并测试事件是否来自div
const onBlur = (e: FocusEvent < HTMLElement > ) => {
if (opened?) {
const element = e.relatedTarget;
if (element == null) {
// dropdown was blured because window lost focused. probably close.
} else if (element != e.currentTarget) {
if (!e.currentTarget.contains(element as Node)) {
// blured element is not in .settings. close
}
}
}
};
这是一个实现这些项目的工具。它没有帮助:/button不断地打开/关闭两次。啊,我很抱歉。它不起作用,因为您的事件侦听器不是在侦听单击事件,而是在侦听鼠标按下。如果您切换到收听点击事件,它将工作!此外,这是解决问题的一种非常常见的方法,请参见这里的相同解决方案:谢谢andre。在我的这个定制钩子上,它对将来的用途是有用的。这有点难理解,但我会努力学习这个技巧。泰,你需要澄清什么?把这些都拿走。它来自打字脚本。我有一个现有的代码示例。我还更新了我的帖子,其中包含了我提议的修改。感谢你突出显示onBlur/onFocus的存在。这大大简化了我的代码。我写得稍微简单一点。为什么你需要这些如果/如果其他?我为测试目的设置了很多嵌套内容。
元素==null
用于dom之外发生的模糊。假设用户单击了另一个选项卡或窗口。元素.contains
是因为下拉列表中可能会出现模糊。假设您在下拉列表中有一个搜索框、复选框等,如果用户将注意力集中在ie上单击,您将触发模糊,您需要知道模糊是否发生在内部。
const onBlur = (e: FocusEvent < HTMLElement > ) => {
if (opened?) {
const element = e.relatedTarget;
if (element == null) {
// dropdown was blured because window lost focused. probably close.
} else if (element != e.currentTarget) {
if (!e.currentTarget.contains(element as Node)) {
// blured element is not in .settings. close
}
}
}
};
const onKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") {
// close!
}
);