You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置history.scrollRestoration为manual无法阻止Safari恢复滚动位置怎么办

Safari scrollRestoration manual 模式锚点滚动兼容方案

问题根因

Safari 对 history.scrollRestoration = "manual" 的实现和 Chrome、Firefox 存在原生差异:

  • Chrome/Firefox 的 manual 模式会完全阻止所有历史导航相关的自动滚动,仅保留锚点点击的默认滚动逻辑
  • Safari 的 manual 模式仅会阻止页面重载时的滚动恢复,不会拦截历史前进/后退时URL锚点对应的自动滚动;同时原生锚点点击逻辑会和自定义 pushState 逻辑冲突,导致点击锚点无响应

兼容修复代码

CSS 代码

html,body,div {
    height: 100vh;
    width: 100vw;
    margin: 0;
    overflow-x: hidden;
}    
#nav {
    display:flex;
    justify-content:center;
    position:fixed;
    width: 100%;
    height: 100px;
    background: rgba(0,0,0,0.7);
}
nav > a {
    display:grid;
    justify-content:center;
    align-items:center;
    text-decoration:none;
    color:white;
    width: 30%;
    height: 90%;
    font-size:120%;
    cursor:pointer;
}
#a1, #blue{
    background-color:blue;
}   
#a2, #red {
    background-color:red;
}

HTML + JS 代码

<body>
    <nav id = "nav">
        <a id = "a1" href = "#blue">BLUE</a> 
        <a id = "a2" href = "#red">RED</a> 
    </nav>
    <div id = "blue"></div>
    <div id = "red"></div>

    <script>
        // 统一设置滚动恢复模式
        if ('scrollRestoration' in window.history) {
            window.history.scrollRestoration = "manual";
        }

        // 处理历史导航,拦截Safari自动滚动
        window.addEventListener("popstate", () => {
            // 记录当前滚动位置,下一帧立即重置,覆盖Safari自动滚动
            const currentScrollY = window.scrollY;
            requestAnimationFrame(() => {
                window.scrollTo(0, currentScrollY);
            });
        });

        // 统一锚点点击行为,解决Safari点击无响应问题
        document.getElementById("a1").addEventListener("click", (e) => {
            e.preventDefault();
            document.getElementById("blue").scrollIntoView();
            window.history.pushState("blue", "", "#blue");
        });
        document.getElementById("a2").addEventListener("click", (e) => {
            e.preventDefault();
            document.getElementById("red").scrollIntoView();
            window.history.pushState("red",  "", "#red");
        });
    </script>
</body>

修复后效果

  • 点击锚点时,所有浏览器都会滚动到对应元素位置,同时推入历史记录
  • 历史前进/后退时,所有浏览器都仅更新URL锚点,不会自动调整页面滚动位置

内容的提问来源于stack exchange,提问作者Cristian Davide Conte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 06:06:03