我们一步步来吧,包括我踩过的坑我也会还原一遍,让大家一起长长见识
遮罩层
遮罩层是最没技术难度的,写个css就可以了。
.mask {
z-index: 1110;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
}
按然后再加个bindtap,控制点击之后消失,感觉直接就可以用了呢。这里有铅笔画不出蜡笔的味道提供的一个代码片段:
https://developers.weixin.qq.com/s/cvqEYzmM7Ffn
突出元素
这个才是难点所在。
1、确定元素位置。
我们首先要找出这个元素的轮廓,这个我是通过boundingClientRect实现的。
const query = wx.createSelectorQuery();
query.select("#gameInfo").boundingClientRect(); //gameInfo就是我们所需要突出展示的元素ID,后续可以用config传入
query.exec(function(res) {
console.log(res);
}
输出如下:
可以看到这个办法很好地取到了所要突出的元素的位置。
2、画出镂空遮罩。
这里我参考了这篇文章:https://www.cnblogs.com/mxdmg/p/10427605.html
文章中的方法一就不说了,又麻烦又浪费空间。
方法二我试了下,展示效果确实不错,但是也如文中所说的,点遮罩的时候会点到底下的元素,肯定会影响效果。
方法三没试,因为感觉有跟二一样的缺点。
方法四也没试,因为一看就知道很麻烦。
方法五把我导向了mask-image,想说能否用这个css属性在遮罩层上挖个洞出来。关于这方面的应用我觉得这篇文章写得挺好的:https://www.zhangxinxu.com/wordpress/2017/11/css-css3-mask-masks/。然而一一试过后,发现这个属性在小程序中好像用不了(也有可能是我哪里出错,反正就是没法生效)。
呵呵。。。以上几种方式折腾了一个晚上。
后来想想,干脆抛开幻想抛开依赖,自力更生。
不搜了,自己土办法画一个。
我用四个view作为遮罩,框出了需要突出的元素。
<view wx:if="{{showGuide}}" class="mask" bindtap="getHidden">
<view class="mask_block" style="width:100%;top:0px;left:0px;height:{{showArea.top}}px"></view> //上
<view class="mask_block" style="width:100%;top:{{showArea.bottom}}px;left:0px;height:100%"></view> //下
<view class="mask_block" style="height:{{showArea.height}}px;top:{{showArea.top}}px;left:0px;width:{{showArea.left}}px"></view> //左
<view class="mask_block" style="height:{{showArea.height}}px;top:{{showArea.top}}px;left:{{showArea.right}}px;width:100%"></view> //右
</view>
上面的showArea就是第一步中取到的元素位置。
这样一来,遮罩中的元素突出就解决了。
3、还有一个坑
本来以为这一步搞定的时候,发现这个镂空的位置竟然还会漂移!在开发工具和真机中的位置不一样,就算同在真机中,这次展示和下次展示的位置也有可能不一样!
这TM是薛定谔的镂空框!
这就是当时的神奇漂移。
经验告诉我,会出现这种不确定性的——
十之八九都和元素的加载是否完成有关系
请好好记住这句话,可以节省你至少一天的调试时间。
是的,坑就在于步骤一的
query.select("#gameInfo").boundingClientRect();
什么时候取的很关键。在小程序布局完成前,你可能会取到一个偏差值,导致了后面的踩坑。
我之前是在组件生命周期(还不清楚组件生命周期的看这里)中attached环节执行,不行。发现手册中还有一个ready,感觉和page中的onReady是一个东西,然而还是不行。。。
看来还是必须等页面的onReady触发之后才能取到完全正确的值。
所以我必须在主页面的onReady事件发生后再来做这个事情。
那么如何确定onReady呢?相当于我必须能够在onReady事件中去调用用户引导组件的初始化函数。。。想来想去,他们两者之间能够互动的也只有setData了。
也就是数据监听器,不懂的点这里。
幸好按计划本来也是要传入配置数组的。于是在pages中的onReady传入配置数组,然后在组件中对配置数组进行监听。
observers: {
'config': function(config) {
if (config) {
this.initMask(config);
}
}
}
如此一来,遮罩层跟元素的突出展示就算完成了。
当然,这样的遮罩层还是有些不足的,例如只支持方形镂空,如果是圆形元素看着就不那么美观。。。好在我目前没有这方面需求,以后有遇到再说吧。