微信小程序中使用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系统手机点击不会穿透了。
版权归原作者 Joke# 所有, 如有侵权,请联系我们删除。