完美解决!Intro.js 单页应用路由切换状态保持实战指南
你是否遇到过这样的尴尬:用户正在浏览产品引导,切换页面后引导突然中断?单页应用(SPA)的路由切换常常导致 Intro.js 引导状态丢失,让用户体验大打折扣。本文将通过 3 个实战步骤,教你如何利用 Intro.js 回调机制与状态保存 API,彻底解决这一痛点。读完本文你将掌握:路由切换时的状态持久化方案、多页面引导流程设计、以及生产环境的异常处理技巧。
问题根源:为什么路由切换会中断引导?
单页应用通过前端路由实现页面无刷新切换,但这会导致 DOM 结构重建。Intro.js 默认将引导状态存储在内存中,当组件卸载时:
- 引导步骤数据随组件销毁丢失
- 高亮元素(HelperLayer)无法定位新页面元素
- 进度状态未持久化导致重新开始
解决方案:Intro.js 状态保持三件套
1. 回调钩子:路由变化的侦察兵
Intro.js 提供完整的生命周期回调,通过 src/packages/tour/callback.ts 定义的 oncomplete 和 onbeforechange 钩子,可在路由切换前保存状态:
introJs.tour()
.oncomplete(() => {
// 保存当前步骤到 localStorage
localStorage.setItem('tourProgress', JSON.stringify({
step: currentStep,
timestamp: Date.now()
}));
// 导航到下一页
router.push('/next-page');
})
.onbeforechange((targetElement, stepIndex) => {
// 验证元素是否存在,避免路由切换时错误
return document.contains(targetElement);
})
.start();
2. 配置选项:定制你的持久化策略
通过 src/packages/tour/option.ts 配置 dontShowAgain 系列参数,可实现跨会话状态保持:
| 参数 | 类型 | 作用 |
|---|---|---|
dontShowAgain | boolean | 启用"不再显示"功能 |
dontShowAgainCookie | string | 存储状态的 Cookie 名称 |
dontShowAgainCookieDays | number | 状态保留天数 |
introJs.tour({
dontShowAgain: true,
dontShowAgainCookie: 'userOnboarding',
dontShowAgainCookieDays: 30
}).start();
3. 多页引导:跨路由步骤串联
example/multi-page/index.html 展示了经典实现,通过 URL 参数传递状态:
// 第一页:完成后跳转并传递状态
document.getElementById('startButton').onclick = function() {
introJs.tour()
.setOption('doneLabel', '下一步')
.oncomplete(function() {
window.location.href = '/second-page?tour=active&step=3';
})
.start();
};
// 第二页:解析 URL 参数恢复引导
if (new URLSearchParams(window.location.search).get('tour') === 'active') {
introJs.tour()
.setOption('steps', secondPageSteps)
.start();
}
实战步骤:从编码到部署
1. 状态保存模块实现
创建状态管理工具函数,封装 localStorage 操作:
// 状态保存工具
const TourPersistence = {
saveProgress(stepData) {
localStorage.setItem('introJsProgress', JSON.stringify({
...stepData,
updatedAt: new Date().toISOString()
}));
},
getProgress() {
const data = localStorage.getItem('introJsProgress');
return data ? JSON.parse(data) : null;
},
clearProgress() {
localStorage.removeItem('introJsProgress');
}
};
2. 路由守卫集成
在 Vue/React 路由守卫中加入状态检查:
// Vue Router 示例
router.beforeEach((to, from, next) => {
const tourProgress = TourPersistence.getProgress();
if (tourProgress && to.path === tourProgress.nextRoute) {
// 恢复引导
window.__INTROJS_RESUME__ = tourProgress;
}
next();
});
3. 异常处理与边界情况
- 元素不存在:使用
autoPosition: true自动调整位置 - 过期状态:添加时间戳检查,超过 24 小时自动重置
- 强制重置:提供管理员接口清除状态
TourPersistence.clearProgress()
生产环境最佳实践
性能优化
- 引导资源懒加载:仅在需要时加载 Intro.js
- 使用 themes/introjs-modern.css 减少 CSS 体积
- 步骤数据分片加载,避免大对象存储
监控与分析
集成错误监控捕获引导异常:
window.addEventListener('introJsError', (e) => {
// 发送错误日志到服务端
logService.captureException(e.detail);
});
总结与扩展阅读
通过回调钩子 + 状态持久化 + 路由协作的三板斧,我们完美解决了单页应用中的引导中断问题。核心要点:
- 利用
oncomplete钩子在路由切换前保存状态 - 使用 Cookie/LocalStorage 实现跨页面数据共享
- 通过 URL 参数传递引导上下文
官方文档:docs/readme.md
高级示例:example/dynamic-start/index.html
API 参考:src/packages/tour/index.ts
希望本文能帮助你构建流畅的用户引导体验,让产品价值直达用户心智。如有疑问,欢迎在项目 GitHub 加速计划 / in / intro.js 提交 issue。
提示:实际项目中建议结合路由库(如 Vue Router、React Router)的导航守卫使用,效果更佳。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考






