关于uni-app H5 列表滑动在ios上会触发点击事件问题记录

1,173 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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页面过程中,一般一些问题总是出现在苹果手机上,无奈呀,苹果手机适配问题还是多的,因此记录一下。