工作需求是这样的,这是一个产品点评页,有一个产品下拉选择框,当点击下拉按钮时,会有一个下拉弹框覆盖在编辑框之上。允许我画一个不是很精致的原先图。
那么问题就来了,textarea是微信小程序原生的组件,下来弹框是自己写的一个组件,而微信小程序原生组件拥有最高的层级,无论自定义的组件的z-index调到多大都无法覆盖在原生组件之上。
一开始拿到需求一顿狂撸后自我感觉还是挺好的,就提测了。结果测试的同事给我提了这么一个bug,就是在安卓的手机上,上层的弹层被下层的编辑框穿透了。如下图:(原谅我打下不太精致的码)
当然,微信也有提供解决原生层级过高这一bug的方案,就是使用cover-view与cover-image这两个原生组件来覆盖到其他原生组件之上,顺手附上微信官方链接:https://developers.weixin.qq.com/miniprogram/dev/component/native-component.html#cover-view%20%E4%B8%8E%20cover-image。但是这两个原生组件也存在各种各样的局限,例如:
而且不能内嵌我们自己的组件。
废话扯完了就来讲一下我的解决方案:
- 首选判断终端机型是ios还是安卓。
- 在textarea同级创建样式与textarea相同的节点(注意不能用textarea标签,最好是用view标签),该节点值围显示编辑框里的文本信息。
- 在上层组件显示的时候,把下面的textarea给隐藏掉,显示上面创建的节点。为什么显示上面的节点呢,就是为了如果上层组件的高度没完全覆盖到下面编辑框,一下子把下面的textarea给隐藏掉,用户会很容易以为自己刚输入的内容不见了,用户体验很不好,所以就用这个刚创建的节点来显示文本内容。
注意: 不能用wx:if来控制textarea的显示与隐藏,得用透明度opacity来控制。因为如果用if来控制,当textarea重新渲染的时候,在安卓机型上容易造成错位。
附上代码:
判断机型:
wx.getSystemInfo({
success: function (res) {
if (res.model.indexOf('iPhone') !== -1) {
// iphone
}
if (/ios/i.test(res.system)){
// ios
}
},
failure(err) {
console.log(err);
}
})
wxml节点:(textShow 为控制显示的变量),具体textShow的控制就看自己的业务逻辑了,就不贴出来了~
<textarea name="content" value="{{content}}" data-name="content" bindblur="setValue" placeholder="点评你的试用感受吧~(5-5000字)" maxlength='5000' placeholder-class="input-place-holder" bindfocus="textFocus" class="{{textShow || isIos ?'':'hide'}}" disabled="{{!hideSkusList}}"focus="{{textShow}}"></textarea>
<view class="textView {{textShow || isIos?'hide':''}} {{content?'':'input-place-holder'}}" bindtap="textFocus">
<text >{{content?content:'点评你的试用感受吧~(5-5000字)'}}</text>
</view>
wxss代码:
textarea.hide,.textView.hide{
opacity: 0;
color: rgba(0, 0,0, 0);
filter: "alpha(opacity=0)";
}
以上为工作过程中遇到的一点小问题,记录一下防止重复踩坑~如有其他意见,欢迎互相交流