持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
问题说明
近期发现在scrollview中的列表在ios真机上滑动一下特别灵敏,每次滑动基本都会触发了点击事件,这样以来用户体验肯定比较差,特此记录一下解决的方式。
问题代码
一般碰到列表我们都是一个for循环对应的数据,如下一个普通的列表,并且设置了对应的点击事件
<view @click="goDetail(item)" class="v-list-room h-flex-x"
v-for="(item,index) in dataList" :key="item.id">
<view class="v-left-content h-flex-x h-flex-center">
<u-image radius="10" width="204rpx" height="195rpx" :src="item.logo">
</u-image>
</view>
<view class="v-right-content h-flex-y">
<text class="tv-content-top">{{item.name}}</text>
<text class="tv-content-bottom">{{item.remark}}</text>
</view>
</view>
那么在正常情况下这个列表是可以滑动的,经过测试安卓手机确实运行没问题,正常滑动,并且可以点击到下一个页面。
但是当用ios手机滑动的时候就出现问题了,每次滑动一下基本都会触发了点击事件,这就不合理了,苹果手机的滑动实在太灵敏了,因此必须作出一些限制。
解决方式
定义好滑动事件touchStart和touchEnd,这里我们用一个mixin混入方式来定义,因为滑动列表在很多界面都可能存在,所以用混入的方式来定义是最好的。
export default {
data() {
return {
delta: 50, //滑动判断
touchStartX: 0, // 触屏起始点x
touchStartY: 0, // 触屏起始点y
}
},
methods: {
/**
* 触摸开始
**/
touchStart(e) {
console.log('触摸开始');
this.touchStartX = e.touches[0].clientX;
this.touchStartY = e.touches[0].clientY;
},
/**
* 触摸结束
* type用来区分哪个页面的点击事件
**/
touchEnd(e, item, type) {
// console.log('func', func)
// debugger;
e.preventDefault(); // 3.阻止默认行为,不阻止事件冒泡
// console.log('触摸结束');
let deltaX = e.changedTouches[0].clientX - this.touchStartX;
let deltaY = e.changedTouches[0].clientY - this.touchStartY;
// X轴的滑动距离大于 delta,且此次事件是以X轴移动为主(左滑或者右滑);
if (Math.abs(deltaX) > this.delta && Math.abs(deltaX) > Math.abs(deltaY)) {
if (deltaX >= 0) {
console.log('右滑');
} else {
console.log('左滑');
}
// Y轴的滑动距离大于 delta,且此次事件是以Y轴移动为主(上滑或者下滑);
} else if (Math.abs(deltaY) > this.delta && Math.abs(deltaX) < Math.abs(deltaY)) {
if (deltaY < 0) {
console.log('上滑');
} else {
console.log('下滑');
}
// 两轴位移都特别小,可以判断是点击
} else if (Math.abs(deltaY) < 25 && Math.abs(deltaX) < 25) {
if (type == 2) {
} else if (type == 1) {
this.$u.route({
url: 'pagesDetail/index/goodDetail',
params: {
id: item.id
}
});
}
} else {
console.log('可能是误触');
}
}
},
onLoad() {
}
}
这里我们主要通过监听滑动事件来做出拦截,然后区分点击还是滑动,不管是横向滑动还是纵向滑动都可以做出对应的判断。
使用方式如下,在需要进行点击事件的元素上,使用@touchstart和@touchend进行监听,即可达到对应操作,这时候就是通过滑动来监听是否属于点击事件了。
<view @touchstart="touchStart" @touchend="touchEnd($event,item,2)" class="v-list-room h-flex-x"
v-for="(item,index) in dataList" :key="item.id">
<view class="v-left-content h-flex-x h-flex-center">
<u-image radius="10" width="204rpx" height="195rpx" :src="item.logo">
</u-image>
</view>
<view class="v-right-content h-flex-y">
<text class="tv-content-top">{{item.name}}</text>
<text class="tv-content-bottom">{{item.remark}}</text>
</view>
</view>
总结
在开发uni-app H5页面过程中,一般一些问题总是出现在苹果手机上,无奈呀,苹果手机适配问题还是多的,因此记录一下。