页面跳转时动画不触发或一闪而过,本质是浏览器发起导航后立即卸载当前页,导致动画被中断;应通过延迟跳转、css动画控制及视觉欺骗等方案实现loading效果。

页面跳转时动画不触发或一闪而过
本质是浏览器在发起导航请求后,会立刻卸载当前页面(包括 JS 执行、定时器、动画帧),导致 setTimeout、requestAnimationFrame 或 CSS 动画还没播完就被中断。不是代码写错了,是生命周期没卡准。
- 别在
window.location.href =前直接 start 动画然后等 300ms —— 大部分浏览器会在赋值后几毫秒内清空 DOM 和 JS 上下文 - 用
history.pushState()+replaceState()配合手动触发跳转,把动画控制权留在当前页 - 必须监听
beforeunload并在里面调用event.preventDefault()?不行,现代浏览器已禁用该行为的自定义提示,且无法阻止跳转本身 - 更可靠的做法:用
navigate事件(Chrome 111+)或降级到click拦截 +fetch()预加载 + 手动渲染,但仅适用于 SPA 场景
纯 HTML 页面间跳转怎么加 loading
没有 JS 路由管理时,唯一可控的时机是「用户点击」到「新页面白屏开始」之间的窗口。得靠视觉欺骗 + 快速响应。
- 给所有外链
<a></a>加class="js-loading-link",绑定click事件 - 点击瞬间显示全屏 loading 层(用
position: fixed+z-index确保盖住一切) - 用
setTimeout(() => { window.location.href = href }, 16)延迟跳转——不是为了等动画,而是让 loading 层有至少一帧时间被渲染出来 - 别用
display: none控制 loading 层,改用opacity: 0+visibility: hidden,避免重排阻塞 - 注意移动端 Safari 对
setTimeout小于 4ms 的处理不一致,16ms(≈1帧)最稳
CSS 动画 vs JS 动画的选择
loading 动画本身该用哪种实现,取决于你能否接受「跳转后动画残留」或「跳转失败时状态混乱」。
- CSS 动画(如
@keyframes spin)更轻量,但一旦页面卸载,动画就停在当前帧,用户可能看到半转的图标卡住 - JS 动画(
setInterval改变transform)可主动清理,但需在跳转前clearInterval,否则有内存泄漏风险 - 推荐折中方案:CSS 动画 +
animation-play-state: paused初始态,点击时设为running,跳转前再设回paused(虽然页面快没了,但能避免视觉突兀) - 别用
transition做 loading,它依赖属性变化触发,而跳转过程里 DOM 已不可控
history.pushState 后如何保持 loading 状态
这是 SPA 路由场景下的典型问题:pushState 不触发页面刷新,但目标内容还没加载完,用户看到的是旧视图空白或错位。
立即学习“前端免费学习笔记(深入)”;
- loading 状态必须由业务逻辑控制,比如 fetch 完数据、Vue 组件 mounted、React
useEffect执行完毕后才隐藏 - 不能依赖
popstate事件来判断“页面切过去了”,因为pushState本身不触发它,只有浏览器前进/后退才触发 - 路由切换时,先 show loading,再
fetch('/new-page.html')或import('./Page.js'),成功后再 render - 如果用
document.write()或innerHTML替换 body,记得清空旧事件监听器,否则 loading 层可能被新内容覆盖却未销毁
load 事件也不代表样式和字体就绪。多数人卡在这一步,然后加个 setTimeout(2000) 硬等,结果网速快时白屏太久,慢时又提前消失。










