前言
日常开发需求中时常会有步骤引导功能,社区中已有不少工具,如: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:showStepNumbers
4: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及之后的版本需要商用授权,或者选择其他工具库。