Gatsby项目main元素使用滚动吸附时方向键滚动失效如何解决?
问题解决方案
方案1:自动聚焦main元素(推荐)
这个方案可以直接解决需要手动点击页面才能激活方向键滚动的问题,同时不会破坏无障碍适配:
- 给
main元素添加tabIndex={-1}属性,该属性仅允许元素被编程式聚焦,不会出现在键盘Tab的导航序列中 - 页面加载/路由跳转后主动触发main元素的聚焦
代码实现
首先在你的Layout/页面组件中给main添加属性:
// 你的Layout组件代码 import { useEffect } from 'react' const Layout = ({ children }) => { useEffect(() => { // 页面加载完成后自动聚焦主内容区 document.querySelector('main')?.focus() }, []) return ( <main tabIndex={-1}> {/* 此处放置你的section和页面内容 */} </main> ) } export default Layout
如果是多页面站点,需要每次路由跳转后都重新聚焦,在项目根目录的gatsby-browser.js中添加以下代码:
// gatsby-browser.js exports.onRouteUpdate = () => { document.querySelector('main')?.focus() }
无障碍影响
该方案完全符合WAI-ARIA无障碍规范:单页应用路由跳转后将焦点移动到主内容区本来就是推荐的最佳实践,能够减少键盘用户和屏幕阅读器用户的导航成本,反而会提升站点的无障碍适配效果,不会产生负面影响。
方案2:移除#gatsby-focus-wrapper的tabindex属性
如果你不想修改main元素的属性,也可以直接移除@reach/router自动添加的tabindex属性:
// 放在Layout组件的useEffect中,或者gatsby-browser.js的onInitialClientRender钩子中 useEffect(() => { const focusWrapper = document.getElementById('gatsby-focus-wrapper') focusWrapper?.removeAttribute('tabindex') }, [])
注意事项
该方案会移除@reach/router原本的路由跳转自动聚焦逻辑,建议搭配方案1中的主内容区自动聚焦逻辑一起使用,避免路由跳转后焦点丢失的无障碍问题。
关于Gatsby内置功能
目前Gatsby没有针对内部滚动+滚动吸附场景的专属配置,上述两种方案都是社区广泛使用的成熟解决方案,没有已知的兼容性问题。
内容的提问来源于stack exchange,提问作者Bdeering
相关产品推荐
相关产品推荐

