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)
连接线。
连接线分为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);
}
}