界面引导库driverjs

一个仅4kb、轻量无依赖的、用于在web端给予用户分步引导的界面库。

p-1.png

driverjs官方文档写得挺好,本文仅做记录整理。

原理

如下图所示,driverjs原理很简单:在webview中增加fix布局的黑色蒙层(zIndex:100002),并将原高亮元素设置relative布局(zIndex:100004)。

因此在使用中需要注意会改变元素的布局方式

p-5.png

安装

1
2
# npm
npm i --save-dev driver.js


1
2
# yarn
yarn add driver.js

或直接引cdn的js和css文件:

1
2
<script src="https://unpkg.com/driver.js/dist/driver.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/driver.js/dist/driver.min.css">

使用

1
2
3
4
5
6
import Driver from 'driver.js';
import 'driver.js/dist/driver.min.css';

// use
const driver = new Driver();
driver.highlight('#create-post'); // 需要高亮突出的DOM元素

效果:

p-1-1

注意,ts项目中,需要引入typs文件进行类型声明(https://github.com/kamranahmedse/driver.js

实例化语法

语法:

1
const instance = new Driver(options)

其中options:{Object}

  • allowClose:{Boolean},是否禁用点击关闭引导的效果。默认为true,如果置为false,则需要通过弹窗popover或者事件instance.reset()进行关闭;
  • opacity: {number},蒙层透明度。默认为0.75
  • className: {String},蒙层的classname
  • animate:{Boolean},是否开启动画,默认为true
  • padding:{Number},边距
  • overlayClickNext:{Boolean},蒙层点击是否能到下一步,默认为false
  • doneBtnText:{String},完成时弹窗按钮文案,默认为Done
  • nextBtnText:{String},下一步弹窗按钮文案,默认为Next
  • prevBtnText:{String},上一步弹窗按钮文案,默认为Previous
  • showButtons:{Boolean},是否显示按钮,默认为false
  • keyboardControl:{Boolean},是否能通过键盘控制,默认为true

默认配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const driver = new Driver({
className: 'scoped-class', // className to wrap driver.js popover
animate: true, // Animate while changing highlighted element
opacity: 0.75, // Background opacity (0 means only popovers and without overlay)
padding: 10, // Distance of element from around the edges
allowClose: true, // Whether clicking on overlay should close or not
overlayClickNext: false, // Should it move to next step on overlay click
doneBtnText: 'Done', // Text on the final button
closeBtnText: 'Close', // Text on the close button for this step
nextBtnText: 'Next', // Next button text for this step
prevBtnText: 'Previous', // Previous button text for this step
showButtons: false, // Do not show control buttons in footer
keyboardControl: true, // Allow controlling through keyboard (escape to close, arrow keys to move)
scrollIntoViewOptions: {}, // We use `scrollIntoView()` when possible, pass here the options for it if you want any
onHighlightStarted: (Element) {}, // Called when element is about to be highlighted
onHighlighted: (Element) {}, // Called when element is fully highlighted
onDeselected: (Element) {}, // Called when element has been deselected
onReset: (Element) {}, // Called when overlay is about to be cleared
onNext: (Element) => {}, // Called when moving to next step on any step
onPrevious: (Element) => {}, // Called when moving to next step on any step
});

可注册回调事件:

1
2
3
4
5
6
onHighlightStarted: (Element) {}, // Called when element is about to be highlighted
onHighlighted: (Element) {}, // Called when element is fully highlighted
onDeselected: (Element) {}, // Called when element has been deselected
onReset: (Element) {}, // Called when overlay is about to be cleared
onNext: (Element) => {}, // Called when moving to next step on any step
onPrevious: (Element) => {}, // Called when moving to next step on any step

实例属性和方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const isActivated = driver.isActivated; // 当前是否激活
driver.moveNext(); // 执行下一步
driver.movePrevious(); // 执行上一步
driver.start(stepNumber = 0); // 执行第stepNumber步
driver.highlight(string|stepDefinition); // 高亮元素或者选择器
driver.reset(); // 重置或者清理
driver.hasHighlightedElement(); // 检查是否含有高量元素
driver.hasNextStep(); // 检查是否还有下一步
driver.hasPreviousStep(); // 检查是否还有上一步

// Prevents the current move. Useful in `onNext` or `onPrevious` if you want to
// perform some asynchronous task and manually move to next step
driver.preventMove();

// Gets the currently highlighted element on screen
const activeElement = driver.getHighlightedElement();
const lastActiveElement = driver.getLastHighlightedElement();
activeElement.getCalculatedPosition(); // Gets screen co-ordinates of the active element
activeElement.hidePopover(); // 关闭弹窗
activeElement.showPopover(); // 显示弹窗

activeElement.getNode(); // Gets the DOM Element behind this element

Input聚焦效果

我们希望在input获取焦点的时候也使用高亮的效果,则可如下:

1
2
3
4
5
6
7
const focusDriver = new Driver();

// Highlight the section on focus
document.getElementById('creation-input')
.addEventListener('focus', (e) => {
focusDriver.focus('#creation-input');
});

效果-获取焦点:

p-2-2

效果-失去焦点:

p-2-1

添加弹窗

如果希望增加引导弹窗,则可以添加popover属性,如:

1
2
3
4
5
6
7
8
9
const driver = new Driver();
driver.highlight({
element: '#some-element',
popover: {
title: 'Title for the Popover',
description: 'Description for it',
position: 'left'
}
});

效果如:

p-3

其中

  • title属性:{String},标题,可写入html
  • description:{String},描述,可写入html

  • position属性可选择为:{String},位置。left, left-center, left-bottom, top, top-center, top-right, right, right-center, right-bottom, bottom, bottom-center, bottom-right, mid-center.

  • showButtons:{Boolean},是否展示弹窗按钮
  • nextBtnText:{String},下一步按钮的文案
  • closeBtnText:{String},关闭按钮的文案
  • prevBtnText:{String},上一步按钮的文案

默认配置:

1
2
3
4
5
6
7
8
9
10
11
12
const stepDefinition = {
element: '#some-item', // DOM元素或选择器
popover: { //
className: 'popover-class', // 弹窗的className
title: 'Title', // 弹窗title
description: 'Description', // 弹窗描述
showButtons: false, // 弹窗底部是否展示按钮
closeBtnText: 'Close', // 关闭按钮的文案
nextBtnText: 'Next', // 下一步按钮的文案
prevBtnText: 'Previous', // 上一步按钮的文案
}
};

多步骤引导

通过driver.defineSteps(),如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const driver = new Driver();
// Define the steps for introduction
driver.defineSteps([
{
element: '#first-element-introduction',
popover: {
className: 'first-step-popover-class',
title: 'Title on Popover',
description: 'Body of the popover',
position: 'left'
}
},
{
element: '#second-element-introduction',
popover: {
title: 'Title on Popover',
description: 'Body of the popover',
position: 'top'
}
},
{
element: '#third-element-introduction',
popover: {
title: 'Title on Popover',
description: 'Body of the popover',
position: 'right'
}
},
]);
// Start the introduction
driver.start();

p-4

定制化

driverjs的工程及源码整体比较简单,可以做一些的定制化改造。

p-6

如果仅是调整样式的话,直接修改src/driver.scss即可,在此不做详细介绍。