常用 HTML 网页返回顶部链接代码:CSS、原生 JS 与 jQuery 写法
“返回顶部”看似是最简单的交互,实现方式却有好几种,性能与体验差别不小:从最原始的空锚点、到 scrollTop 赋值、再到动画缓动与 CSS scroll-behavior。本文把常用写法列全,并说明各自该在什么时候用。

一、最省事:纯 CSS 一行搞定
现代浏览器支持在 CSS 里声明滚动行为:
html { scroll-behavior: smooth; }
这样所有锚点跳转(<a href="#top">、scrollIntoView、scrollTo)都会自动带平滑动画。配合页面顶部一个 <span id="top"> 或直接用 <a href="#top">返回顶部</a> 即可,零 JS。
想只对某次滚动平滑,可以不用全局 CSS,改为:
window.scrollTo({ top: 0, behavior: 'smooth' });
兼容性说明:Safari 15.4+ 才支持 scroll-behavior: smooth,旧版会静默变成瞬移,因此需要动画一致性时仍要用 JS 方案。
二、原生 JS 的三种写法
1. 直接赋值(无动画,最兼容)
document.getElementById('toTop').onclick = function () {
document.documentElement.scrollTop = 0; // 标准模式
document.body.scrollTop = 0; // 兼容怪异模式(无 doctype 时)
};
注意 scrollTop 要同时写 documentElement 和 body:有 `` 时生效的是 documentElement,缺 doctype 时是 body,只写一个就会在某些老页面失效。
2. requestAnimationFrame + 缓动(可控动画)
function backTop(duration = 400) {
const start = window.pageYOffset;
const dist = -start;
const t0 = performance.now();
function step(now) {
const p = Math.min(1, (now - t0) / duration);
const e = 1 - Math.pow(1 - p, 3); // easeOutCubic
window.scrollTo(0, start + dist * e);
if (p < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
用 requestAnimationFrame 而不是 setInterval 的原因是它会跟显示器刷新对齐、页面不可见时自动暂停,不会掉帧或空转。
3. scrollIntoView
document.querySelector('header').scrollIntoView({ behavior: 'smooth', block: 'start' });
好处是不用算位置,也能正确处理容器内滚动(比如一个 overflow:auto 的长列表要滚回顶部)。
三、jQuery 写法(老项目常见)
$('#toTop').on('click', function () {
$('html, body').animate({ scrollTop: 0 }, 500);
return false; // 阻止 a 标签默认跳转
});
必须同时选 html, body,原因和上面 doctype 一样。jQuery 的 animate 内部已经做了节流,不必再套定时器。
四、显示/隐藏逻辑
常见的“滚过一屏才出现按钮”要注意节流:
let ticking = false;
window.addEventListener('scroll', () => {
if (ticking) return;
ticking = true;
requestAnimationFrame(() => {
btn.classList.toggle('show', window.pageYOffset > window.innerHeight * 0.8);
ticking = false;
});
}, { passive: true });
两个细节:passive: true 让浏览器不必等你的回调就能滚动,明显降低卡顿;用 ticking 标志把一帧内的多次 scroll 合并成一次计算。
五、无障碍与移动端注意点
- 按钮要有可读文本或
aria-label="返回顶部",纯图标时键盘用户必须能 Tab 到; - 点击后应把焦点送到页面主标题(
main.focus()需tabindex="-1"),否则读屏用户仍停在底部; - 长页面推荐提供“跳到主内容”的 skip link,比返回顶部更实用;
- iOS Safari 上
document.body.scrollTop与documentElement.scrollTop行为不一致,统一改用window.scrollTo()最稳; - 如果页面用了虚拟滚动/固定表头,返回顶部后要手动触发一次数据重载,否则会出现“回到顶部但内容是第 20 屏”的错位。
六、常见问题 FAQ
问:为什么我点了 <a href="#"> 反而跳到顶部了?
答:这本来就是浏览器的默认行为(# 指向文档顶端)。但它是瞬移且会往 URL 加个 #,还可能被历史记录干扰,建议写成 href="#top" 并在 JS 里 preventDefault。
问:动画过程中用户手动滚页面会打架吗?
答:会。用 rAF 方案时,可在 scroll 或 wheel/touchmove 事件里取消动画(保存 id 并 cancelAnimationFrame)。
问:iframe 内页面怎么让父页面滚回顶部?
答:跨 iframe 不能直接改父页 scrollTop,用 window.parent.postMessage('toTop','*'),父页监听消息后自己滚。
选型建议:只要“能回去”就用 CSS scroll-behavior;要自定义动画曲线或兼容旧浏览器用 rAF;容器内滚动用 scrollIntoView。
生产内容,同时打通搜索引擎(SEO)与AI搜索引擎(GEO)流量入口的软件! 点击进入365建站器 »
