微信小程序中使用map组件,ios手机中点击地图上的view,会触发底下的markertap,只要底下如果有marker点的话。
这就造成了用户体验不是很好。
然后无意间我发现点击能滑动的scroll-view反而不会触发底下的markertap,就等于是一个不穿透的容器。我就在想是不是view也可以换成scroll-view,然后防止穿透点击,答案是:可以。
但是体验还是不太好,因为scroll-view会滑动,所以按钮里面的内容也会滑动,不是最佳的解决方法。于是,我就想到可以用透明的可滑动的scroll-view放在上层作为隐形按钮,下层放普通的按钮样式,这回真正的解决了ios的bug。
一、地图上覆盖的子组件代码
wxml代码
<view class="box"><swiper circular><swiper-item wx:for="{{switchArr}}"><view class="container" catchtap="switchItem" data-index="{{index}}" data-name="{{item.name}}"><view class="card"><view class="content"><view class="icon"><image src="{{item.imageUrl}}" mode="aspectFill"></image></view><view class="bt"><view class="title">{{item.name}}</view></view></view></view></view><scroll-view class="scroll-view" scroll-y="true" catchtap="switchItem" data-index="{{index}}" data-name="{{item.name}}"><view style="height:100vh;"></view></scroll-view></swiper-item></swiper><view class="cancelSwitch" style="top:{{statusHeight+3}}px" catchtap="cancelSwitch"><text>退出页面</text></view></view>
less代码
/* pages/subPack/otherAnimation/index.wxss */page {box-sizing: border-box;font-family: sans-serif;}.cancelSwitch{position: absolute;left: 40rpx;display: flex;align-items: center;justify-content: center;width: 210rpx;height: 60rpx;line-height: 60rpx;border-radius: 30rpx;color:#fff;background-color: #d94251;image{width: 35rpx;height: 30rpx;margin-left: 3rpx;}}.box{position: fixed;z-index: 10000;min-height: 100vh;background-color: #1a1c22;width: 100%;swiper {width: 100%;height: 100vh;swiper-item {width: 100%;height: 100vh;display: flex;flex-direction: column;justify-content: center;align-items: center;.container {position: relative;display: flex;justify-content: space-around;align-items: center;width: 710rpx;.card {width: 100%;margin: 20px;padding: 40px 30px;border-radius: 40px;background-color: #20252a;border: 4rpx solid #ffefa1;box-shadow: -0px -0px 10px #ffefa1;.imgBx {position: relative;text-align: center;}.content {text-align: center;display: flex;flex-wrap: wrap;justify-content: center;align-items: center;.icon {padding: 20px;margin-top: 15px;height: 100%;width: 120%;border-radius: 40px;color: #32a3b1;font-size: 16px;overflow: hidden;text-decoration: none;background: #20252a;box-shadow: 13px 13px 26px #181c20, -13px -13px 26px #282e35;image {width: 100%;border-radius: 10px;}}.bt {display: inline-block;padding: 10px 20px;margin-top: 45px;border-radius: 40px;color: #ffefa1;font-size: 16px;text-decoration: none;background: #20252a;box-shadow: 20px 20px 41px #161a1d,-20px -20px 41px #2a3037;&:hover {background: #20252a;box-shadow: inset 20px 20px 41px #161a1d,inset -20px -20px 41px #2a3037;}}}&:hover {background: #20252a;box-shadow: inset 20px 20px 41px #161a1d,inset -20px -20px 41px #2a3037;}}}.scroll-view{width: 750rpx;background-color: #fff;position:absolute;height: 1000rpx;opacity: 0;}}}}
js代码
const app = getApp();Component({data: {statusHeight: app.globalData.statusHeight,buttonCanUse:true},properties: {switchArr:{type:Array,value:[]}},methods: {switchItem(e) {if(!this.data.buttonCanUse){return}this.setData({buttonCanUse:false})this.triggerEvent('switchItem', {index:e.currentTarget.dataset.index,name:e.currentTarget.dataset.name})this.setData({buttonCanUse:true})},cancelSwitch() {this.triggerEvent('cancelSwitch')},}})
二、小程序效果
map效果:map上面有很多点位 这些点位都是可以点击进去其他页面的点
切换旅游路线的子组件:是覆盖在map之上的一个容器 z-index:10000
点击就可以切换到路线
三、问题所在
点击这个全景路线的时候 如果点击的位置下方有一个marker点,则他触发两个点击事件,即同时切换路线 同时进入marker点链接的路径
四、解决思路
利用可滑动的scroll-view不会穿透的特性,在子组件上面插入隐形scroll-view,设置点击事件,(用户以为点击的是子组件,实际上点击的是scroll-view,这是一个通用的思路),然后将scroll-view大小覆盖子组件
五、代码分析
核心代码:
<view class="container" catchtap="switchItem" data-index="{{index}}" data-name="{{item.name}}"><view class="card"><view class="content"><view class="icon"><image src="{{item.imageUrl}}" mode="aspectFill"></image></view>view class="bt"><view class="title">{{item.name}}</view></view></view></view></view> <scroll-view class="scroll-view" scroll-y="true" catchtap="switchItem" data-index="{{index}}" data-name="{{item.name}}"><view style="height:100vh;"></view></scroll-view>
.scroll-view{width: 750rpx;background-color: #fff;position:absolute;height: 1000rpx;opacity: 0;}
<view class="container" catchtap="switchItem" data-index="{{index}}" data-name="{{item.name}}">是子组件里面每个路线的容器,点击可以切换路线
我在同级写了一个scroll-view 设置宽度750rpx撑满屏幕 然后高度1000rpx盖住整个路线容器 并且将透明度改为零(即opacity:0)
然后在wxml中 设置scroll-y=“true” 在scroll-view里面放一个高度100vh的盒子,让整个scroll-view可滑动,因为scroll-y,所以是上下滑动。
这里为什么不设置scroll-x=“true” 然后在横向上滑动 是因为 我本身用了swiper组件 左右滑动切换,用scroll-x的话,两个滑动事件会冲突,会影响原有的滑动感受。然后在scroll-view上
然后在scroll-view上添加原本写在container上面的点击的点击事件,让用户点的实际上是scroll-view
这样就可以保证ios系统手机点击不会穿透了。