创建第一个 Tour
Driver.js 的多步骤引导由两部分组成:
steps:描述每一步高亮哪个元素、显示什么内容。drive():启动引导流程。
准备页面元素
假设页面里有三个需要说明的区域:
<header id="top-nav">顶部导航</header>
<button id="create-project">创建项目</button>
<section id="project-list">项目列表</section>
定义步骤并启动
import { driver } from "driver.js";
import "driver.js/dist/driver.css";
const driverObj = driver({
showProgress: true,
steps: [
{
element: "#top-nav",
popover: {
title: "顶部导航",
description: "这里可以切换工作区、搜索内容和打开个人设置。",
side: "bottom",
align: "start",
},
},
{
element: "#create-project",
popover: {
title: "创建项目",
description: "点击这个按钮创建一个新的项目。",
side: "left",
align: "center",
},
},
{
element: "#project-list",
popover: {
title: "项目列表",
description: "你创建或参与的项目会显示在这里。",
side: "top",
align: "start",
},
},
],
});
document.querySelector("#start-tour").addEventListener("click", () => {
driverObj.drive();
});
代码演示
点击演示中的“开始引导”按钮,可以看到一个完整的多步骤页面导览。
源码
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Driver.js 基础 Tour 演示</title>
<link rel="stylesheet" href="/driver-js/vendor/driver.css">
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
background: #eef4ff;
color: #172033;
font-family: Arial, "Microsoft YaHei", sans-serif;
}
.app {
min-height: 520px;
padding: 22px;
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 18px;
padding: 14px 18px;
border: 1px solid #d7e3f7;
border-radius: 8px;
background: #fff;
box-shadow: 0 10px 30px rgba(37, 99, 235, 0.08);
}
.brand {
font-size: 18px;
font-weight: 700;
color: #1d4ed8;
}
.toolbar {
display: flex;
align-items: center;
gap: 10px;
}
button {
cursor: pointer;
border: 0;
border-radius: 6px;
padding: 9px 14px;
font-weight: 700;
}
.primary {
background: #2563eb;
color: #fff;
}
.secondary {
border: 1px solid #cbd5e1;
background: #fff;
color: #334155;
}
.layout {
display: grid;
grid-template-columns: 170px 1fr;
gap: 18px;
}
.sidebar,
.content,
.card,
.panel {
border: 1px solid #d7e3f7;
border-radius: 8px;
background: #fff;
}
.sidebar {
padding: 14px;
}
.menu-item {
margin-bottom: 8px;
border-radius: 6px;
padding: 10px 12px;
color: #475569;
font-size: 14px;
}
.menu-item.active {
background: #dbeafe;
color: #1d4ed8;
font-weight: 700;
}
.content {
padding: 18px;
}
.cards {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
margin-bottom: 16px;
}
.card {
padding: 14px;
}
.label {
color: #64748b;
font-size: 13px;
}
.value {
margin-top: 8px;
font-size: 24px;
font-weight: 800;
color: #0f172a;
}
.panel {
padding: 18px;
}
.task {
display: flex;
justify-content: space-between;
gap: 12px;
border-bottom: 1px solid #e2e8f0;
padding: 12px 0;
color: #334155;
}
.task:last-child {
border-bottom: 0;
}
</style>
</head>
<body>
<main class="app">
<header id="top-nav" class="topbar">
<div class="brand">项目控制台</div>
<div class="toolbar">
<button id="start-tour" class="secondary" type="button">开始引导</button>
<button id="create-project" class="primary" type="button">创建项目</button>
</div>
</header>
<section class="layout">
<aside id="side-menu" class="sidebar">
<div class="menu-item active">概览</div>
<div class="menu-item">成员</div>
<div class="menu-item">账单</div>
<div class="menu-item">设置</div>
</aside>
<section class="content">
<div id="metrics" class="cards">
<article class="card">
<div class="label">活跃项目</div>
<div class="value">12</div>
</article>
<article class="card">
<div class="label">本周任务</div>
<div class="value">48</div>
</article>
<article class="card">
<div class="label">成员</div>
<div class="value">9</div>
</article>
</div>
<div id="project-list" class="panel">
<strong>最近项目</strong>
<div class="task"><span>官网改版</span><span>进行中</span></div>
<div class="task"><span>数据看板</span><span>待审核</span></div>
<div class="task"><span>移动端适配</span><span>已完成</span></div>
</div>
</section>
</section>
</main>
<script type="module">
import { driver } from "/driver-js/vendor/driver.js.mjs";
const driverObj = driver({
showProgress: true,
nextBtnText: "下一步",
prevBtnText: "上一步",
doneBtnText: "完成",
steps: [
{
element: "#top-nav",
popover: {
title: "顶部导航",
description: "这里放置全局操作,右侧按钮可以随时重新打开本引导。",
side: "bottom",
align: "start",
},
},
{
element: "#create-project",
popover: {
title: "创建项目",
description: "点击这里创建一个新项目,这是新用户最常用的入口。",
side: "left",
align: "center",
},
},
{
element: "#side-menu",
popover: {
title: "侧边菜单",
description: "项目、成员、账单和设置等模块可以从这里切换。",
side: "right",
align: "start",
},
},
{
element: "#project-list",
popover: {
title: "最近项目",
description: "用户可以从列表继续处理最近访问过的项目。",
side: "top",
align: "start",
},
},
],
});
document.querySelector("#start-tour").addEventListener("click", () => {
driverObj.drive();
});
</script>
</body>
</html>
Step 的基本结构
一个 step 通常包含:
| 字段 | 说明 |
|---|---|
element |
要高亮的元素,可以是 CSS 选择器,也可以是 DOM 元素 |
popover |
弹层配置对象 |
popover.title |
弹层标题 |
popover.description |
弹层正文 |
popover.side |
弹层相对目标元素的位置 |
popover.align |
弹层在该方向上的对齐方式 |
element 也可以省略。没有目标元素的步骤会把弹层显示在页面中心,适合做欢迎语或总结页。
const driverObj = driver({
steps: [
{
popover: {
title: "欢迎",
description: "接下来用一分钟了解这个控制台。",
},
},
{
element: "#create-project",
popover: {
title: "创建项目",
description: "从这里开始。",
},
},
],
});
何时启动 Tour
常见启动时机有三种:
| 时机 | 适合场景 |
|---|---|
| 用户点击帮助按钮 | 用户主动学习,不打扰正常操作 |
| 新用户首次进入页面 | 入门型后台、工作台、编辑器 |
| 新功能发布后 | 对新入口或重要变化做提示 |
首次自动启动时,建议用 localStorage 记录是否已经展示过:
const TOUR_KEY = "dashboard-tour-shown";
if (!localStorage.getItem(TOUR_KEY)) {
driverObj.drive();
localStorage.setItem(TOUR_KEY, "1");
}
编写步骤的原则
- 每一步只解释一个元素。
- 标题尽量短,正文说明用户能做什么。
- 不要把完整帮助文档塞进弹层。
- 关键按钮或危险操作需要明确说明后果。
- 引导步骤通常控制在 3 到 6 步更容易读完。