jQuery平滑滚动到指定元素并更新URL hash无跳转实现问题
问题原因
直接给window.location.hash赋值会触发浏览器原生的锚点跳转逻辑,该逻辑不受你点击事件中e.preventDefault()的影响,因此自定义滚动动画结束后,浏览器会再次直接滚动到对应锚点位置,就会出现跳转抖动的问题。
解决方案
使用HTML5提供的history系列API更新地址栏hash,这类API只会修改地址栏的显示内容,不会触发浏览器的默认锚点滚动行为。
修改后的完整代码如下:
$('.smoothscroll').on('click',function(e) { if (/#/.test(this.href)) { if (document.location.pathname == "/") { e.preventDefault(); var offset = headerHeight; var target = this.hash; // 增加目标元素存在性校验,避免报错 if ($(target).length === 0) return; $('html, body').stop().animate({ 'scrollTop': $(target).offset().top - offset }, 500, 'swing', function() { // 支持history API的场景用replaceState更新hash,不触发滚动 if (history.pushState) { // 若需要保留锚点访问历史、支持浏览器后退到上一个锚点,可替换为history.pushState history.replaceState(null, null, target); } else { // 极低版本浏览器降级方案,非必需 window.location.hash = target; } }); }; }; });
补充说明
replaceState不会在浏览器历史记录中新增条目,用户点击后退按钮不会回溯之前点击的锚点;如果需要保留锚点访问历史,将replaceState替换为pushState即可。- 新增的目标元素存在性校验,可以避免页面没有对应ID元素时出现JS报错。
内容的提问来源于stack exchange,提问作者Junky
相关产品推荐
相关产品推荐

