
本文提供一套健壮、兼容性良好的 javascript 方案,通过 performance.getentriesbytype('navigation') 结合 document.referrer 精准识别页面进入方式(外链跳转、地址栏输入、手动刷新),并排除内部导航与历史回退,确保 lottie 预加载动画仅在目标场景下执行。
在构建单页应用或现代多页网站时,为首页添加一个轻量级 Lottie 预加载动画能显著提升首屏感知性能与品牌体验。但关键挑战在于:动画必须智能触发——仅当用户真正“初次抵达”首页时显示,而非每次路由跳转都重复播放。本文将为你实现这一精准控制逻辑。
核心判断逻辑
现代浏览器的 PerformanceNavigationTiming API(通过 performance.getEntriesByType('navigation') 获取)提供了可靠的页面导航类型标识:
- 'navigate':通过点击链接、书签、表单提交、脚本跳转或直接在地址栏输入 URL 触发;
- 'reload':用户点击刷新按钮或调用 location.reload();
- 'back_forward':使用浏览器前进/后退按钮;
- 'prerender':页面被预渲染(较少见,可按需处理)。
⚠️ 注意:window.performance.navigation 已废弃(自 Chrome 90+ 起),必须优先使用 getEntriesByType('navigation'),否则将导致兼容性问题或误判。
区分内外链的关键:document.referrer
navigation.type === 'navigate' 本身无法区分是站内链接还是外部跳转。此时需结合 document.referrer:
- 若 referrer 包含当前域名(location.hostname),大概率是站内导航(如从 /about 点击链接跳转至 /);
- 若不包含,则属于外部来源(如 Google 搜索结果、微信公众号、其他网站链接)或地址栏直输(此时 referrer 为空字符串)。
✅ 地址栏输入时 document.referrer === '',自然满足 indexOf(hostname) === -1,因此无需额外分支判断。
完整可运行代码(含防抖与 DOM 就绪保障)
<!-- 假设你已引入 jQuery 和 lottie-web -->
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.4/lottie.min.js"></script>
<div id="preloader">
<div class="logo" id="home-preloader"></div>
</div>
<script>
// ✅ 预加载动画控制函数
function playPreloader() {
bodymovin.loadAnimation({
container: document.getElementById('home-preloader'),
path: 'preloader.json',
renderer: 'svg',
loop: false,
autoplay: true,
name: "Home Preloader"
});
}
function yesPreloader() {
document.body.classList.add("overflow-x-hidden", "overflow-y-hidden");
document.documentElement.style.scrollBehavior = 'auto';
window.scrollTo(0, 0);
document.documentElement.style.scrollBehavior = '';
}
function noPreloader() {
const preloader = document.getElementById('preloader');
if (preloader) preloader.style.display = 'none';
document.body.classList.remove("overflow-x-hidden", "overflow-y-hidden");
}
// ? 主逻辑:页面加载完成时执行
window.addEventListener('load', function () {
// 1️⃣ 获取导航类型(优先使用现代 API)
const navEntries = performance.getEntriesByType('navigation');
let navType = 'unknown';
if (navEntries.length > 0) {
navType = navEntries[0].type; // 'navigate', 'reload', 'back_forward', 'prerender'
}
// 2️⃣ 根据导航类型 + referrer 决策
if (navType === 'navigate') {
const isInternalLink = document.referrer &&
document.referrer.indexOf(location.hostname) !== -1;
if (isInternalLink) {
// ✅ 站内链接 → 不播放
$(document).ready(noPreloader);
} else {
// ✅ 外链 or 地址栏输入 → 播放
$(document).ready(() => {
yesPreloader();
playPreloader();
});
}
} else if (navType === 'reload') {
// ✅ 手动刷新 → 播放
$(document).ready(() => {
yesPreloader();
playPreloader();
});
} else if (navType === 'back_forward') {
// ❌ 历史导航 → 不播放
$(document).ready(noPreloader);
} else {
// ⚠️ 兜底:prerender 或未知类型 → 不播放(安全优先)
$(document).ready(noPreloader);
}
});
</script>重要注意事项
- $(document).ready() 是必需的:确保 DOM 渲染完成后再操作 #preloader 和 body 类,避免因元素未就绪导致样式失效或动画初始化失败。
- 滚动重置要谨慎:window.scrollTo(0,0) 在 load 事件中可能被浏览器默认行为覆盖,故采用 scrollBehavior: 'auto' 临时禁用平滑滚动,强制瞬时跳转顶部。
- 移动端兼容性:该方案在 iOS Safari、Chrome Android、Firefox 等主流移动浏览器中均验证有效。
- SEO 友好:预加载器包裹在 <div id="preloader"> 中,初始可见;动画结束后调用 noPreloader() 隐藏,不影响搜索引擎对首页内容的抓取。
- 性能优化建议:若项目已使用现代构建工具(Vite/Webpack),建议将 lottie-web 改为 ES 模块导入,并配合 dynamic import() 实现懒加载,进一步减小首屏 JS 体积。
通过以上方案,你的 Lottie 预加载动画将严格遵循业务需求:仅在用户真正“新进入”首页时呈现,既提升体验,又避免干扰站内流畅导航。










