前言
日常开发需求中时常会有步骤引导功能,社区中已有不少工具,如:shepherdjs、 driver.js、introjs等,使用方式都大同小异。本文主要介绍一下intro.js的使用和遇到的问题。
官网文档:introjs.com/docs/
开始
安装 npm install intro.js --save
intro.js自带几种不同的主题样式需要额外引入,也可以引入自定义样式。
// 引入JS、CSS
import introJs from 'intro.js'
import 'intro.js/minified/introjs.min.css'
// 引入主题样式或者自定义样式
import './introjs-custom.scss'
intro.js有Tour步骤引导和Hints提示两种功能,
Tour:
Hints:
本文主要介绍一下Tour。
Tour
introJs().setOptions()声明实例。简单例子如下:
<div class='card'>...</div>
...
const intro = introJs().setOptions({
...,
// 定义步骤
steps:[
{
element: document.querySelector('.card'),// 也可以直接'.card'
title: '标题',
intro: '内容',
position: 'top', // 单个提示出现位置
}
]
})
// 启动
intro.start()
title和intro内支持直接写html:
title: `<img src=${img} />`,
intro: '<b>你好!</b><br/> We also used some HTML tags!'
setOptions部分配置:
文案类:nextLabel、prevLabel 、doneLabel、skipLabel
自定义类: tooltipClass、 highlightClass、buttonClass、progressBarAdditionalClass
展示类:1:showBullets、2:showProgress、3:showStepNumbers4:showButtons
其他用到的配置:
exitOnOverlayClick覆盖层点击退出;overlayOpacity覆盖层透明度;stepNumbersOfLabel修改of文案hidePrev隐藏第一步的上一步按钮,默认展示禁用状态按钮;scrollToElement自动滚动至视窗外元素;disableInteraction禁用高亮处交互。
遇到的问题
Intro.js支持定位高亮可滚动元素,但是某些布局下,在适当屏高的时候有异常:高亮元素未正常滚动至可见区。
解决思路:
- 关闭自动滚动:
scrollToElement: false; - 找到目标
element。 introJs().onbeforechange()回调函数中手动滚动至高亮位置:element.scrollIntoView({ block: 'center', inline: 'nearest' });
introJs().onbeforechange(async () => {
return new Promise((resolve) => {
console.log(this.intro)
});
})
在回调函数中打印intro实例,通过_currentStep、_direction字段可以知道目标element。
_direction有两种情况[forward, backward],对应的_currentStep如下:
最后配置内容如下:
const baseImportDom = document.querySelector('.base-import-button')
const mapInputDom = document.querySelector('.map-input')
const operationDom = document.querySelector('.operation-icon'),
this.intro = introJs()
.setOptions({
showButtons: true,
showBullets: false,
// tooltipClass: 'customTooltip',
// highlightClass: 'customHighlight',
// buttonClass: 'customButton',
disableInteraction: true,
scrollToElement: false,
hidePrev: true,
exitOnOverlayClick: true,
overlayOpacity: 0,
showStepNumbers: true,
stepNumbersOfLabel: '/',
nextLabel: '下一步',
prevLabel: '上一步',
doneLabel: '开始体验',
steps: [
{
element: mapInputDom,
title: `<img src=${firstStepGif} />`,
intro:
'<div>xxxx</div>',
},
{
element: operationDom,
title: `<img src=${secondStepGif} />`,
intro:
'<div>xxxx</div><div>xxxxxxxx</div>',
},
{
element: baseImportDom,
title: `<img src=${thirdStepGif} />`,
intro:
'<div>xxxx</div><div>xxxxxxxx</div>',
position: 'top',
},
],
}).onbeforechange(async () => {
return new Promise((resolve) => {
const scrollMap = {
forward: {
2: baseImportDom,
},
backward: {
1: mapInputDom,
},
}
scrollMap[this.intro._direction][
this.intro._currentStep
]?.scrollIntoView({ block: 'center', inline: 'nearest' })
resolve()
})
})
总结
intro.js的使用比较容易上手,文档也很友好。 不过值得注意的是,它的开源协议是AGPL-3.0,如果项目是商用的,引用v2.0.0及之后的版本需要商用授权,或者选择其他工具库。