sunilwang

V1

2023/02/21阅读:41主题:绿意

前端引导的实现

一、为什么需要引导

在产品经理这个行当里面,一直有一句老话“要把用户当成傻子”。这句话并没有任何敌视用户的意思,其理论无非是“让用户减少学习成本,让用户容易上手,是产品设计里面的核心追求”。

对于经常混迹于互联网的人们来说,对于一个新功能甚至新产品可以做到边使用边摸索,但不能保证所有人都具备这个能力。而且随着应用的功能越来越丰富,使用传统的文档已经不能满足用户追求快速的需求了,而想要更直观的突出对应的功能,则免不了使用引导系统来快速帮助用户了解功能。

二、如何实现一个引导

某在线文档产品的引导
某在线文档产品的引导

图片比文字更具象,上图就是一个典型的引导。从图片可以看出,引导包括一个蒙层,一个高亮区域和一个弹窗。其中高亮的区域就是引导的目标对象,而弹窗内则是当前引导的内容,用来向用户介绍一些相关的信息。

还有一种引导没有蒙层,同样也就不存在直观的高亮区域。与没有蒙层的引导相比,有蒙层的引导能够更好的吸引用户的注意力,让用户能够更快速的了解到产品的功能。

1、引导的核心功能

目标对象

很容易理解,我们在实现一个引导时,想要向用户展示的对象或步骤中的某一步,就是引导对象。引导对象可以是一个按钮,也可以是一个区域。当有蒙层存在时,引导的目标对象往往会是一个高亮的元素。

引导内容

引导内容是对引导对象的补充说明。它的表现形式通常是一个弹窗,通过一些简明扼要的文字向用户介绍引导对象的作用,以及在整个功能中的位置。

引导内容通常还会包括一些可以点击的按钮,比如“下一步”或者“完成”,这说明引导的可能是一个流程。

2、实现引导的几种方式

实现引导的方式有很多种,比如蒙层拼接、边框计算、克隆元素、堆叠顺序以及 SVG 绘制等,这里我们主要介绍克隆元素、堆叠顺序和 SVG 绘制三种方式。

克隆元素

故名思义,克隆元素的方式就是通过 Node.cloneNode,复制对应目标元素,生成引导目标对象的方法。

采用这种方法,需要将克隆的元素添加到蒙层之上,并通过一系列定位手段,如margintranslateposition等实现克隆元素与目标元素的重合。

核心代码如下:

// 获取引导蒙层
const mask = document.querySelector('#mask');
// 获取目标元素
const targetNode = document.querySelector('#targetNode');
// 获取目标元素位置
const { x, y, width, height } = targetNode.getBoundingClientRect();
// 克隆元素
const cloneNode = targetNode.cloneNode(true);

// 设置克隆元素定位
cloneNode.style = `
    margin-left: ${x}px;
    margin-top: ${y}px;
`
;
// 将克隆元素添加到蒙层上
mask.appendChild(cloneNode);

由于需要使克隆元素与目标元素重叠,当页面的位置或内容发生变化时,需要重新计算克隆元素的位置。

另外,由于此方式需要对目标元素进行克隆,消耗相对较大,而且克隆元素不能克隆事件,所以克隆元素的方式也只适合结构简单,没有复杂操作的页面。

堆叠顺序

堆叠顺序的核心思路是通过更改目标元素z-index的值,使目标元素展示在蒙层之上。

与克隆元素方式相比,采用堆叠顺序方式的引导,用户可以直接对目标元素进行交互,比如当目标元素是一个按钮的时候,可以触发按钮的点击事件并执行相应的流程。同样,堆叠顺序方式也有它的缺点:当目标元素的父元素样式中包括position: fixed/absolute/sticky时,目标元素的z-index无法超过蒙层。

也就是说,采用堆叠顺序方式实现的引导,只有当页面布局比较简单的时候适用。

SVG绘制

我们先来了解一下什么是 SVG。SVG 全名为可缩放矢量图形(Scalable Vector Graphics),基于 XML 标记语言,用于描述二维的矢量图形。

path 元素是 SVG 基本形状中最强大的一个,它不仅能创建其他基本形状,还能创建更多其他形状。

下面是一个 SVG 绘制形状的例子: SVG示例

SVG 写法如下:

<svg width="100%"
     height="100%"
     viewBox="0 0 400 400"
     xmlns="http://www.w3.org/2000/svg"
>

    <path d="M 100 100 L 300 100 L 200 300 z"
          fill="orange"
          stroke="black"
          stroke-width="3"
    />

</svg>

path 元素的形状是通过属性 d 来定义的,属性 d 的值是一个“命令+参数”的序列。因为属性 d 采用的是用户坐标系统,所以不需标明单位。

路径命令是对要绘制的路径的说明。每一个命令由代表命令的字母和代表参数的数字组成。

SVG 定义了六种路径命令类型,一共 20 条命令:

  • 移动到:M、m
  • 画线至:L、l、H、h、V、v
  • 三次方贝塞尔曲线:C、c、S、s
  • 二次方贝塞尔曲线:Q、q、T、t
  • 椭圆曲线:A、a
  • 封闭路线:Z、z

命令是大小写敏感的。大写的命令指定绝对坐标,而小写命令指定相对(于当前位置的)坐标。

可以将负值作为命令的参数:

  • 负的角度是逆时针的;
  • 绝对坐标中,负的 x 和 y 将被解释为负坐标;
  • 相对坐标中,负的 x 值为向左移动,负的 y 值为向上移动。

这里我们主要使用 SVG 的 path 元素来绘制一个镂空的蒙层,来达到高亮目标元素的目的。

核心代码如下:

<template>
    <!-- SVG 蒙层 -->
    <svg id="svg-mask"
         class="svg-mask"
         width="100vw"
         height="100vh"
         version="1.1"
         xmlns="http://www.w3.org/2000/svg"
    >

        <path d=""
              fill="rgba(0, 0, 0, .3)"
        />

    </svg>
</template>

<style lang="scss">
.svg-mask {
 position: fixed;
 z-index: 10002;
 pointer-events: none;

 > path {
  pointer-events: all;
 }
}
</style>

绘制 path 的代码:

const svgMask = document.querySelector('#svg-mask');
const path = svgMask.querySelector('path');
const { width: vw, height: vh } = svgMask.getBoundingClientRect();
const targetNode = document.querySelector('#targetNode');
const { x, y, width, height } = targetNode.getBoundingClientRect();
const pathD = `M 0 0 H ${vw} V ${vh} H 0 Z M ${x} ${y} v ${height} h ${width} v ${-height} h ${-width} Z`;

path.setAttribute('d', pathD);

从代码可以看出,我们为 SVG 设置了pointer-events: none,同时为 path 设置了pointer-events: all,也就是说用 SVG 绘制的蒙层的点击事件是不允许穿透的,而目标元素所对应位置的镂空允许点击事件穿透,这样在展示引导的同时,用户也可以与目标元素进行交互。

3、引导弹窗

在确定了目标元素的位置后,我们还需要将引导弹窗定位到目标元素附近。根据目标元素位置的不同,我们提供了12种定位方式,如下图所示:

引导弹窗定位方式
引导弹窗定位方式

我们把12种定位分为两类情况:

  • 4种居中的情况;
  • 其余8种斜角。

第一种情况,弹窗的箭头始终位于弹窗边缘居中的位置,对于 top 和 bottom,箭头的位置是弹窗宽度的 1/2,而对于 left 和 right,箭头的位置则是弹窗高度的 1/2。

第二种情况,箭头所在的位置相对于弹窗顶点存在一个固定的偏移量,当然这个偏移量的值也可以通过配置去设置。

值得一提的是,上面图片中 top 与 bottom,left 与 right 的位置相对于引导弹窗是相反的,这是因为图中的 top 与 bottom 等位置关系,是相对于引导目标元素,而不是弹窗本身的,需要反向映射一下。

三、总结

不管是新用户还是老用户,在产品发布新版本、有新功能上线或是现有功能更新的场景下,都需要一定的引导。与产品介绍视频、使用手册等方式相比,前端引导与产品 UI 融合在一起,不会给用户割裂的交互感受。

实现前端引导的方式也有很多种,随着技术的发展与更新还会产生更多新的方式,但万变不离其宗的就是如何带给用户更好的体验。使用 SVG 绘制的方式既能兼顾引导的展现与性能,又能在产品交互上带来一些新的体验,也是我们目前比较推荐的方式。

作者介绍

莫日根:LBG前端工程师。对游戏与视频播放器开发有一些心得,目前主要负责家服用户侧业务并致力于前端性能与稳定性提升工作。

分类:

前端

标签:

前端

作者介绍

sunilwang
V1