0. 本文参考

https://ask.dcloud.net.cn/article/38074

1. 使用场景

  • 监听手指向右滑动,触发返回事件
  • 监听手指向左滑动,拉出元素的更多功能,如删除
  • 防止页面滑动时误触发Click事件,也是我的出发需求,在uni-app开发时,向下滑动一个列表,如果恰好起始位置是一个click组件,即使滑动一段距离,@click事件还是会触发,因此想通过 @touch 区别开

2. 组件代码(touch-listen.vue)

<template>
	<view @touchstart="touchStart" @touchend="touchEnd">
		<slot></slot>
	</view>
</template>

<script>
	export default {
		name: "touch-listen",
		props: {
			delta: {
				type: Number,
				default: 50
			}
		},
		data() {
			return {
				touchStartX: 0, // 触屏起始点x  
				touchStartY: 0, // 触屏起始点y  
			};
		},
		methods: {
			/**  
			 * 触摸开始  
			 **/
			touchStart(e) {
				console.log("触摸开始")
				this.touchStartX = e.touches[0].clientX;
				this.touchStartY = e.touches[0].clientY;
			},

			/**  
			 * 触摸结束  
			 **/
			touchEnd(e) {
				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("右滑")
						this.$emit('fingerToR')
					} else {
						console.log("左滑")
						this.$emit('fingerToL')
					}
				// Y轴的滑动距离大于 delta,且此次事件是以Y轴移动为主(上滑或者下滑);
				} else if (Math.abs(deltaY) > this.delta && Math.abs(deltaX) < Math.abs(deltaY)) {
					if (deltaY < 0) {
						console.log("上滑")
						this.$emit('fingerToT')
					} else {
						console.log("下滑")
						this.$emit('fingerToB')
					}
				// 两轴位移都特别小,可以判断是点击
				} else if (Math.abs(deltaY) < 25 && Math.abs(deltaX) < 25) {
					console.log("点击")
					this.$emit('fingerClick')
				} else {
					console.log("可能是误触")
				}
			},
		}
	}
</script>

组件可传参数:delta,代表当前偏差容忍度,偏差距离大于此会被判定为滑动,默认50(比较低),可以根据自己需求测试调整。

3. 使用方法

使用该组件将你想要监听的区域包裹起来;
如:监听页面内右滑返回

// 可以设定一个最小高度,以便没有被内容撑开导致空白处无法监听到事件
<touch-listen class="page-wrap" style="min-height: 80vh;" @fingerToR="back">
	<h1>content<h1>
</touch-listen>

method:{
	back() {
		// 手指向右滑动,想返回
	}
}

或是,更加精细的click判断,不会在滑动中误触发点击事件

<touch-listen @fingerClick="click">
	<button>content<button>
</touch-listen>=

4. 注意事项

在监听页面右滑返回时,如果组件内本身就有可左滑右滑的组件,如Swiper,或者Scroll,
这时候我们滑动内部组件也会触发全局的监听,因此我们需要在不想监听的元素上包裹一下。
加上这两个东西防止事件向父元素冒泡:@touchstart.stop @touchend.stop

<view @touchstart.stop @touchend.stop>
	<swiper>
		// balabala
	</swiper>
</view>
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐