React多页面应用:关闭手动提示横幅后恢复页面焦点问题求助
React横幅关闭后焦点恢复解决方案
提前锁定活跃元素
不要等到点击关闭按钮时才去获取document.activeElement——此时焦点已经转移到关闭按钮上了。正确的做法是在横幅开始显示的瞬间,立即记录当前页面的活跃元素:// 父组件中触发横幅显示的逻辑 const prevActiveEl = useRef<HTMLElement | null>(null); const showStatusBanner = () => { // 存储当前活跃元素到ref prevActiveEl.current = document.activeElement as HTMLElement; setBannerVisible(true); };用
useRef存储这个引用比状态更可靠,不会因为重渲染丢失数据。关闭时精准恢复焦点
在横幅的关闭回调中,直接调用存储元素的focus()方法,优先排除body元素:// 横幅组件的关闭处理函数 const handleDismiss = () => { // 先恢复焦点再执行关闭逻辑 if (prevActiveEl.current && prevActiveEl.current.tagName !== 'BODY') { prevActiveEl.current.focus(); // 恢复后清空ref,避免重复触发 prevActiveEl.current = null; } // 执行横幅隐藏逻辑 onClose(); };处理边缘情况
- 如果存储的元素已经被卸载(比如用户在横幅显示期间切换了页面组件),可以通过
document.contains(prevActiveEl.current)判断元素是否存在于DOM中,不存在的话就 fallback 到页面的主要内容容器(比如带role="main"的元素)。 - 如果之前的元素是不可聚焦的(比如无tabindex的div),可以提前给这类元素设置
tabindex="-1",确保能通过focus()聚焦。
- 如果存储的元素已经被卸载(比如用户在横幅显示期间切换了页面组件),可以通过
避免默认焦点抢占
有些横幅组件的关闭按钮会自动获取焦点,这时候要确保焦点恢复逻辑在横幅隐藏前执行,或者在关闭按钮的点击事件中先处理焦点再隐藏组件,防止浏览器自动把焦点切回body。
内容的提问来源于stack exchange,提问作者ConfusionMaster
相关产品推荐
相关产品推荐

