JavaScript 页面引导页实现方案对比与组件化实践

作者:木棉时间:2026-10-26 13:10:56浏览:223

本文总结了JavaScript页面引导页的两种实现思路。首先分析基于PNG图片镂空的方案,指出其因图片尺寸与屏幕分辨率不匹配导致的定位误差大、交互不精确等缺陷,不建议在生产环境使用。随后重点介绍基于组件封装的通用引导方案,通过传入包含title、content、target等字段的数据结构,结合getBoundingClientRect获取元素位置,实现高亮显示与内容引导。文章还涵盖了自定义逻辑注入及intro.js、driver.js等第三方库的使用建议,为开发者提供从简单到专业的完整解决方案。

实现思路1

采用PNG图片格式,将需要高亮的部分镂空,其余部分使用半透明遮罩。如图所示,这种方法实现简单,但存在较大的误差。

实现思路1

其效果如图所示,点击“下一步”等按钮时,无法精准对应图片中预设的“下一步”按钮区域。即使尝试通过getBoundingClientRect方法获取元素位置,依然会存在显著误差。因此,该思路仅作为一种参考方案,由于精度不足,不太推荐使用。

实现思路1

实现思路2

通过组件封装的方式,外层使用时传入相应的数据结构。以我的页面为例,数据结构包含title、content、target、entry、leave等字段,具体可根据实际需求配置,但target字段为必选,用于指定需要高亮展示的目标元素,并在其旁侧显示content引导内容。

  const stepData = [{
    title: '组件库和图标',
    content: '从基础组件、自定义业务组件、图标库中拖拽组件或图标到画布区域进行页面编排组装',
    target: '#editPageLeftSideBar',
    entry: () => void,
    leave: () => void
  }]

实现思路1

组件内部实现下一步切换的公共逻辑。若存在非公共逻辑,可将相关方法定义在stepData中,并在组件的下一步方法里进行调用。

    const clearCls = () => {
        document.body.querySelectorAll('.guide-highlight').forEach(el => {
          el.classList.remove('guide-highlight')
        })
     }

    const addCls = (target) => {
       target.classList.add('guide-highlight');
    }

    const getTarget = () => {
        const currentStep = props.stepData[state.currentStepIndex]
        return document.querySelector(currentStep.target)
    }
    
    const onGoNext = () => {
        // 清除所有的高亮class, 因为我是通过class样式来控制的
        clearCls()

        // 查找下一步的目标对象
        const currentStep = props.stepData[state.currentStepIndex]
        const $stepTarget = getTarget()

        // 给target添加class
        addCls()

        // 执行其它方法,譬如上面的leave/entry方法
        if (typeof state.currentStep.leave === 'function') {
          state.currentStep.leave()
        }
        if (typeof currentStep.entry === 'function') {
          currentStep.entry()
        }

        // 计算引导容器的位置style

        const windowWidth = window.innerWidth
        const windowHieght = window.innerHeight
         const {
          top: targetTop,
          right: targetRight,
          bottom: targeBottom,
          left: targetLeft,
          width: targetWidth
        } = $stepTarget.getBoundingClientRect()
        const {
          width,
          height
        } = tipRef.value.getBoundingClientRect()
        let placement = 'left'
        if (width > height
          && targeBottom < 0.3 * windowHieght) {
          placement = targeBottom > 0.5 * windowHieght ? 'top' : 'bottom'
        } else {
          placement = targetLeft > 0.5 * windowWidth ? 'left' : 'right'
        }

        let styles = {}

        if (placement === 'bottom') {
          styles = {
            top: `${targeBottom + 10}px`,
            left: `${targetLeft + (targetWidth - width) / 2}px`
          }
        } else if (placement === 'top') {
          styles = {
            top: `${windowHieght - targetTop - height - 10}px`,
            left: `${targetLeft + (targetWidth - width) / 2}px`
          }
        } else if (placement === 'left') {
          styles = {
            top: `${targetTop}px`,
            right: `${windowWidth - targetLeft + 10}px`
          }
        } else if (placement === 'right') {
          styles = {
            top: `${targetTop}px`,
            left: `${targetRight + 10}px`
          }
        }
    }

插件

可选用intro.js、driver.js等成熟的第三方库。

到此这篇关于js页面引导页的实现思路总结的文章就介绍到这了,更多相关js 引导页内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

作者最新文章