
本文介绍一种可靠方案:利用 cookie 暂存选中的教程名称,在目标页面加载完成后主动触发 intro.js 教程,避免因页面跳转导致的教程闪现或中断问题。
本文介绍一种可靠方案:利用 cookie 暂存选中的教程名称,在目标页面加载完成后主动触发 intro.js 教程,避免因页面跳转导致的教程闪现或中断问题。
在使用 Intro.js 构建多视图引导教程时,一个常见痛点是:希望用户从侧边栏菜单点击某教程项后,先跳转到对应页面,再立即启动该教程;但若直接在跳转前调用 introJs().start(),由于页面重定向(window.location.href)会中断 JS 执行流,导致教程仅闪现一帧便消失。
上述问题的根本原因在于:JavaScript 无法跨页面生命周期保持执行上下文。因此,正确的解法是将“启动指令”持久化传递至目标页面,并在新页面 DOM 完全就绪后执行。
✅ 推荐实现方案:Cookie + 页面级初始化
我们采用轻量、无依赖的 Cookie 机制暂存选中教程标识,并在目标页面通过 window.addEventListener('load') 统一触发:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
1. 修改下拉菜单按钮逻辑(仅设置 Cookie + 跳转)
function setSelectedTour(tourName, url) {
// 设置有效期为 3 秒的临时 Cookie(足够覆盖页面跳转)
document.cookie = `selectedTour=${tourName}; path=/; max-age=3`;
if (url) {
window.location.href = url;
}
}
⚠️ 注意:max-age=3 确保 Cookie 在教程启动后自动过期,避免意外复用;path=/ 保证所有路径均可读取。
2. 目标页面自动检测并启动教程
在每个可能被教程跳转的目标页面(如 validate.html、activity_feed.html)中,添加以下初始化脚本:
// 读取 Cookie 中的教程标识
function getSelectedTour() {
const name = "selectedTour=";
return document.cookie
.split(';')
.map(c => c.trim())
.find(row => row.startsWith(name))
?.substring(name.length) || '';
}
// 根据名称加载并启动教程(步骤数据建议外置 JSON)
function startTour(tourName) {
fetch('/config/stepsTours.json')
.then(res => {
if (!res.ok) throw new Error('Failed to load tour steps');
return res.json();
})
.then(data => {
const steps = data[tourName] || [];
if (steps.length === 0) {
console.warn(`No steps defined for tour: ${tourName}`);
return;
}
introJs()
.setOptions({
steps,
showProgress: true,
showBullets: false,
disableInteraction: true,
exitOnEsc: true,
exitOnOverlayClick: true
})
.start();
})
.catch(err => console.error('Tour initialization failed:', err));
}
// 页面加载完成后检查并启动(关键!)
window.addEventListener('load', () => {
const tour = getSelectedTour();
if (tour) {
// 清除 Cookie,防止刷新后重复触发
document.cookie = 'selectedTour=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;';
startTour(tour);
}
});
✅ 优势总结
- 零闪现:教程严格在新页面 load 后启动,DOM 和资源完全就绪;
- 解耦清晰:菜单只负责“下发指令”,页面只负责“响应执行”,职责分离;
- 可扩展性强:新增教程只需在 stepsTours.json 中添加配置,无需修改 JS 逻辑;
- 用户体验友好:支持 ESC/点击遮罩退出,且自动清理状态,杜绝误触发。
? 提示:若项目已使用 localStorage 或状态管理库(如 Vuex/Pinia),也可替换 Cookie 为更现代的持久化方式,但需确保跨页面可读性与及时清理机制。










