创建第一个 Tour

Driver.js 的多步骤引导由两部分组成:

  • steps:描述每一步高亮哪个元素、显示什么内容。
  • drive():启动引导流程。

准备页面元素

假设页面里有三个需要说明的区域:

html
<header id="top-nav">顶部导航</header>
<button id="create-project">创建项目</button>
<section id="project-list">项目列表</section>

定义步骤并启动

js
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, &quot;Microsoft YaHei&quot;, 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>

&lt;section class=&quot;layout&quot;&gt;
  &lt;aside id=&quot;side-menu&quot; class=&quot;sidebar&quot;&gt;
    &lt;div class=&quot;menu-item active&quot;&gt;概览&lt;/div&gt;
    &lt;div class=&quot;menu-item&quot;&gt;成员&lt;/div&gt;
    &lt;div class=&quot;menu-item&quot;&gt;账单&lt;/div&gt;
    &lt;div class=&quot;menu-item&quot;&gt;设置&lt;/div&gt;
  &lt;/aside&gt;

  &lt;section class=&quot;content&quot;&gt;
    &lt;div id=&quot;metrics&quot; class=&quot;cards&quot;&gt;
      &lt;article class=&quot;card&quot;&gt;
        &lt;div class=&quot;label&quot;&gt;活跃项目&lt;/div&gt;
        &lt;div class=&quot;value&quot;&gt;12&lt;/div&gt;
      &lt;/article&gt;
      &lt;article class=&quot;card&quot;&gt;
        &lt;div class=&quot;label&quot;&gt;本周任务&lt;/div&gt;
        &lt;div class=&quot;value&quot;&gt;48&lt;/div&gt;
      &lt;/article&gt;
      &lt;article class=&quot;card&quot;&gt;
        &lt;div class=&quot;label&quot;&gt;成员&lt;/div&gt;
        &lt;div class=&quot;value&quot;&gt;9&lt;/div&gt;
      &lt;/article&gt;
    &lt;/div&gt;

    &lt;div id=&quot;project-list&quot; class=&quot;panel&quot;&gt;
      &lt;strong&gt;最近项目&lt;/strong&gt;
      &lt;div class=&quot;task&quot;&gt;&lt;span&gt;官网改版&lt;/span&gt;&lt;span&gt;进行中&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;task&quot;&gt;&lt;span&gt;数据看板&lt;/span&gt;&lt;span&gt;待审核&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;task&quot;&gt;&lt;span&gt;移动端适配&lt;/span&gt;&lt;span&gt;已完成&lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;
&lt;/section&gt;

</main>

<script type="module"> import { driver } from "/driver-js/vendor/driver.js.mjs";

const driverObj = driver({
  showProgress: true,
  nextBtnText: &quot;下一步&quot;,
  prevBtnText: &quot;上一步&quot;,
  doneBtnText: &quot;完成&quot;,
  steps: [
    {
      element: &quot;#top-nav&quot;,
      popover: {
        title: &quot;顶部导航&quot;,
        description: &quot;这里放置全局操作,右侧按钮可以随时重新打开本引导。&quot;,
        side: &quot;bottom&quot;,
        align: &quot;start&quot;,
      },
    },
    {
      element: &quot;#create-project&quot;,
      popover: {
        title: &quot;创建项目&quot;,
        description: &quot;点击这里创建一个新项目,这是新用户最常用的入口。&quot;,
        side: &quot;left&quot;,
        align: &quot;center&quot;,
      },
    },
    {
      element: &quot;#side-menu&quot;,
      popover: {
        title: &quot;侧边菜单&quot;,
        description: &quot;项目、成员、账单和设置等模块可以从这里切换。&quot;,
        side: &quot;right&quot;,
        align: &quot;start&quot;,
      },
    },
    {
      element: &quot;#project-list&quot;,
      popover: {
        title: &quot;最近项目&quot;,
        description: &quot;用户可以从列表继续处理最近访问过的项目。&quot;,
        side: &quot;top&quot;,
        align: &quot;start&quot;,
      },
    },
  ],
});

document.querySelector(&quot;#start-tour&quot;).addEventListener(&quot;click&quot;, () =&gt; {
  driverObj.drive();
});

</script> </body> </html>

Step 的基本结构

一个 step 通常包含:

字段 说明
element 要高亮的元素,可以是 CSS 选择器,也可以是 DOM 元素
popover 弹层配置对象
popover.title 弹层标题
popover.description 弹层正文
popover.side 弹层相对目标元素的位置
popover.align 弹层在该方向上的对齐方式

element 也可以省略。没有目标元素的步骤会把弹层显示在页面中心,适合做欢迎语或总结页。

js
const driverObj = driver({
  steps: [
    {
      popover: {
        title: "欢迎",
        description: "接下来用一分钟了解这个控制台。",
      },
    },
    {
      element: "#create-project",
      popover: {
        title: "创建项目",
        description: "从这里开始。",
      },
    },
  ],
});

何时启动 Tour

常见启动时机有三种:

时机 适合场景
用户点击帮助按钮 用户主动学习,不打扰正常操作
新用户首次进入页面 入门型后台、工作台、编辑器
新功能发布后 对新入口或重要变化做提示

首次自动启动时,建议用 localStorage 记录是否已经展示过:

js
const TOUR_KEY = "dashboard-tour-shown";

if (!localStorage.getItem(TOUR_KEY)) {
  driverObj.drive();
  localStorage.setItem(TOUR_KEY, "1");
}

编写步骤的原则

  • 每一步只解释一个元素。
  • 标题尽量短,正文说明用户能做什么。
  • 不要把完整帮助文档塞进弹层。
  • 关键按钮或危险操作需要明确说明后果。
  • 引导步骤通常控制在 3 到 6 步更容易读完。