使用Next/Link跳转页面时跳过无障碍skip-link组件的问题求助
问题根因
这个问题是Next.js客户端路由的已知行为:使用<Next/Link>跳转属于客户端无刷新跳转,页面不会触发完整重载,浏览器不会自动重置焦点位置到页面顶部。页面被缓存时,之前的焦点状态会被保留,就会出现首次按Tab直接跳过最顶部skip-link的情况。
可行解决方案
方案1:路由跳转后手动重置页面焦点(兼容性最好,全版本适用)
在全局布局中监听路由变化,每次跳转完成后手动重置焦点到页面起始位置,即可让首次按Tab时优先聚焦最顶部的skip-link组件。
如果你使用的是Pages路由:
import { useEffect } from 'react' import { useRouter } from 'next/router' function MyApp({ Component, pageProps }) { const router = useRouter() useEffect(() => { const resetFocusAfterRouteChange = () => { document.body.tabIndex = -1 document.body.focus() document.body.removeAttribute('tabIndex') } router.events.on('routeChangeComplete', resetFocusAfterRouteChange) return () => router.events.off('routeChangeComplete', resetFocusAfterRouteChange) }, [router.events]) return <Component {...pageProps} /> } export default MyApp
如果你使用的是Next 13+ App路由:
'use client' import { useEffect, usePathname } from 'next/navigation' export default function RootLayout({ children }) { const pathname = usePathname() useEffect(() => { // 路径变化时重置焦点到页面顶部 document.body.tabIndex = -1 document.body.focus() document.body.removeAttribute('tabIndex') }, [pathname]) return ( <html lang="zh-CN"> <body> <!-- skip-link组件需放在body下的第一个可聚焦元素位置 --> <a href="#main-content" id="skip-link">跳转到主内容</a> <!-- 其他布局代码 --> {children} </body> </html> ) }
方案2:修正Link组件写法(适用于Next 13+版本)
Next 13之后的版本已经支持直接在<Link>组件上传递所有a标签的属性,不需要额外嵌套a标签,嵌套写法本身也可能导致焦点处理异常,改为如下写法即可:
<Link href="/search" aria-label="Search Page" className="header__search"> Search </Link>
内容的提问来源于stack exchange,提问作者Shoaib Ahmed
相关产品推荐
相关产品推荐

