新手引导组件introjs

1,304 阅读1分钟

前言

日常开发需求中时常会有步骤引导功能,社区中已有不少工具,如: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: tour.gif
Hints: hints.gif
本文主要介绍一下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部分配置:

文案类:nextLabelprevLabeldoneLabelskipLabel
自定义类: tooltipClasshighlightClassbuttonClassprogressBarAdditionalClass
展示类:1:showBullets、2:showProgress、3:showStepNumbers4:showButtons
image.png
其他用到的配置:

  • exitOnOverlayClick覆盖层点击退出;
  • overlayOpacity覆盖层透明度;
  • stepNumbersOfLabel修改of文案
  • hidePrev 隐藏第一步的上一步按钮,默认展示禁用状态按钮;
  • scrollToElement自动滚动至视窗外元素;
  • disableInteraction禁用高亮处交互。

遇到的问题

Intro.js支持定位高亮可滚动元素,但是某些布局下,在适当屏高的时候有异常:高亮元素未正常滚动至可见区。

image.png

解决思路:

  1. 关闭自动滚动:scrollToElement: false;
  2. 找到目标element
  3. introJs().onbeforechange()回调函数中手动滚动至高亮位置:element.scrollIntoView({ block: 'center', inline: 'nearest' })
introJs().onbeforechange(async () => {
  return new Promise((resolve) => {
       console.log(this.intro)
  });
})

在回调函数中打印intro实例,通过_currentStep_direction字段可以知道目标element

image.png

_direction有两种情况[forward, backward],对应的_currentStep如下:
image.png

最后配置内容如下:

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及之后的版本需要商用授权,或者选择其他工具库。