Guide封装方法梳理

126 阅读3分钟

1.调用startGuide方法

创建guideWrapperDom(真实DOM)

它是一个真实DOM,被添加到body中。document.body.appendChild(guideWrapperDom);

创建NormalGuideView(React元素)

将React元素挂载到真实DOM上

ReactDOM.render(reactEle, viewDom);

2.NormalGuideView

收集真实DOM

遍历steps数组,一个常见的steps数组如下所示:

const originalStep = [
  {
    key: "first_guide",
    extra: "退出引导",
    title: "自动解除限售地区上线啦[我是标题]",
    content:
      "自动解除限售地区是一个新功能,商家开启次功能后,如果限售地区物流商恢复正常,那么系统会自动解除对该地区的限售[我是content内容]",
    placement: "bottom",
  },
  {
    key: "second_guide",
    title: "一单多品运费规则已到这里了",
    content:
      "自动解除限售地区是一个新功能,商家开启次功能后,如果限售地区物流商恢复正常,那么系统会自动解除对该地区的限售[我是content内容]",
    placement: "bottom",
  },
];

可以看出,其中的key属性,就是相应的html标签上的data属性:

<div className={styles.container}>
  <div className={styles.first} data-guide="first_guide">
    这里是新手引导的第一步
  </div>
  <div className={styles.second} data-guide="second_guide">
    这里是新手引导的第二步
  </div>
</div>

通过document.querySelector([data-guide=first_guide]);可以获取到dom对象。然后将dom对象添加到option的属性中。

  {
    key: "second_guide",
    title: "一单多品运费规则已到这里了",
    content:
      "自动解除限售地区是一个新功能,商家开启次功能后,如果限售地区物流商恢复正常,那么系统会自动解除对该地区的限售[我是content内容]",
    placement: "bottom",
  },

使用MASK挡住网页所有内容

<NormalGuideView />返回2个元素:

    <div>
      <Mask zIndex={zIndex} />
      <NodrmalGuide {...options} steps={steps} />
    </div>

其中MASK元素盖住整个页面,zIndex = 999999。<NodrmalGuide />覆盖于MASK之上。

.mask {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}

3.NodrmalGuide

resiezeStyle钩子

首先,获取当前Step对应的真实DOM。获取真实元素的width、left、top、height:

export const getOffset = (element) => {
  const docEl = document.documentElement;
  const scrollTop = docEl.scrollTop;
  const scrollLeft = docEl.scrollLeft;
  const rec = element.getBoundingClientRect();
  return {
    top: rec.top + scrollTop,
    width: rec.width,
    height: rec.height,
    left: rec.left + scrollLeft,
  };
};

以上获取的CSS属性,width、left、top、height可以给白色方块来用(wrapperStyle

最外层DIV(wrapperStyle)

Zindex是父亲组件的Zindex+1.width、left、top、height是通过resizeStyle计算出来的wrapperStyle

第一个子元素(normalActiveWrapper)

一句话概括作用:黑色背景。 由于它是wrapperStyle的子元素,所以它的大小正好和引导元素一样。那么如何黑色覆盖整个页面呢?答案是让boxShadow阴影半径无限大。

boxShadow参数含义:

1.水平偏移 2.垂直偏移 3.模糊半径(越大越模糊)4.阴影半径(值越大,阴影范围越大) 5.颜色

 <div
    className={styles.normalActiveWrapper}
    style={{
      boxShadow: `0 0 0 100px rgba(0,0,0,0.6)`,
    }}
  />

第二个子元素(normalConnectWrapper)

连接线。

image.png

连接线分为4种情况。在白框的下面,左面,右面,上面。

1.如果连接线在白框下面

最外层套一个normalBottom

.normalBottom {
  .normalConnectWrapper {
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
  }

}

2.如果连接线在白框上面

.normalTop {
  .normalConnectWrapper {
    bottom: 100%;
    left: 50%;
    transform: rotate(180deg) translateX(-50%);
  }

}

3.如果连接线在白框左面

.normalLeft {
  .normalConnectWrapper {
    top: calc(50% - 16px);
    left: -24px;
    transform: rotate(90deg);
  }

  .normalContentWrapper {
    right: calc(100% + 34px);
  }
}

4.如果连接线在白框右面

.normalRight {
  .normalConnectWrapper {
    left: calc(100% + 12px);
    transform: rotate(-90deg);
    top: calc(50% - 16px);
  }

  .normalContentWrapper {
    left: calc(100% + 34px);
  }
}