我们在写手机端的网页的时候,往往会添加一些手势的操作来增加用户的体验,比如左滑,右滑,上滑,下滑,这个方向的操作
在操作之前我们要认识touch这个只有在手机端才有的函数事件,也就是滑动事件
1.touch事件
这里用到的是touchstart,touchmove,touchend 这三个事件,分别代表的是 滑动的开始,滑动中,滑动的结束,可以传一个事件对象参数event.
document.addEventListener('touchstart',(e)=>{
console.log(e,'event');
});
document.addEventListener('touchmove',(e)=>{
console.log(e,'event');
});
document.addEventListener('touchend',(e)=>{
console.log(e,'event');
});
我们可以通过事件对象的preventDefault方法来阻止默认事件 这样不会跟我们写的操作产生冲突
document.addEventListener('touchstart',(e)=>{
console.log(e,'event');
e.preventDefault()
});
在参数里面我们主要是看有一个 touches的数组,这个就是记录你手指滑动的信息,至于为啥是个数组,因为滑动不仅有单手指,也有可能是多手指 比如 扩大,缩小这类操作的,
touches数组里面记录手指滑动在当前屏幕的位置相关信息,我们可以通过这个来进行操作
2.判断滑动位置
我这里是用的vue的写法,原生的写法也是差不多,里面的逻辑处理是一样的,不同的是变量的拿取和赋值
第一步的先监听滑动的开始touchstart
/* 监听滑动开始 */
touchstart(e) {
/* 阻止一些默认事件 */
e.preventDefault();
/* 记录初始位置 */
this.startX = e.touches[0].pageX;
this.startY = e.touches[0].pageY;
},
第二步: 监听滑动移动的操作
/* 监听滑动移动 */
touchmove(e) {
/* 判断是否滚动 */
this.isMove = true;
/* 监听滑动最终结束的位置 */
this.endX = e.touches[0].pageX;
this.endY = e.touches[0].pageY;
},
第三部:监听滑动结束,进行数据判断操作方向
判断的原理
1. 因为的坐标轴是从左上角为原点 向右X轴越大,向下Y轴越大
2.先判断左右,移动的X轴触摸点的最终值如果比初始值大,那就证明是从左往右,即为右滑,反正就是从右往左,即为左滑
3.在判断上下 移动的Y轴触摸点的最终值如果比初始值大,那就证明是从上往下,即为下滑,反正就是从下往上,即为上滑
if(x > 0){
console.log('向右');
}else if(x < 0 ){
console.log('向左');
}else if(y > 0){
console.log('向下');
}else if(y < 0){
console.log('向上');
}
如果按照这个去判断 会发现上下滑动的会出现问题,因为会发现它不会走向上向下,会在向左向右那里判断就进入了,在这里可能就有人会这么,那我先判断上下,再来判断左右,那样的话,也是一样,不过出现问题的是左右滑动,所以这里我们要加些特殊处理,让他更精确一点,判断横纵移动距离的对比
通过这个我们发现,当横向滑动的时候,X的绝对值会远远大于Y,而纵向滑动的时候,Y的绝对值会远远大于X,那我们可以在原来的代码开始加个条件判断
/* 监听滑动结束 */
touchend(e) {
/* 判断移动方向 */
let X = this.endX - this.startX,
Y = this.endY - this.startY;
/* 判断是否移动还是点击 */
if (this.isMove) {
if (X > 0 && Math.abs(X) > Math.abs(Y)) {
//向右
console.log('向右');
} else if (X < 0 && Math.abs(X) > Math.abs(Y)) {
//向左
console.log('向左');
} else if (Y > 0 && Math.abs(Y) > Math.abs(X)) {
//向下
console.log('向下');
} else if (Y < 0 && Math.abs(Y) > Math.abs(X)) {
//向上
console.log('向上');
} else {
//没有
console.log('没有');
}
} else {
console.log('没有');
}
/* 判断滚动结束 */
this.isMove = false;
},
完整的代码
<template>
<div @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" class="page">
</div>
</template>
<script>
export default {
data() {
return {
/* 移动所需参数 */
startX: 0,
startY: 0,
endX: 0,
endY: 0,
isMove: false,
}
},
methods: {
/* 监听滑动开始 */
touchstart(e) {
/* 阻止一些默认事件 */
e.preventDefault();
/* 记录初始位置 */
this.startX = e.touches[0].pageX;
this.startY = e.touches[0].pageY;
},
/* 监听滑动移动 */
touchmove(e) {
/* 判断是否滚动 */
this.isMove = true;
/* 监听滑动最终结束的位置 */
this.endX = e.touches[0].pageX;
this.endY = e.touches[0].pageY;
},
/* 监听滑动结束 */
touchend(e) {
/* 判断移动方向 */
let X = this.endX - this.startX,
Y = this.endY - this.startY;
/* 判断是否移动还是点击 */
if (this.isMove) {
if (X > 0 && Math.abs(X) > Math.abs(Y)) {
//向右
console.log('向右');
} else if (X < 0 && Math.abs(X) > Math.abs(Y)) {
//向左
console.log('向左');
} else if (Y > 0 && Math.abs(Y) > Math.abs(X)) {
//向下
console.log('向下');
} else if (Y < 0 && Math.abs(Y) > Math.abs(X)) {
//向上
console.log('向上');
} else {
//没有
console.log('没有');
}
} else {
console.log('没有');
}
},
}
}
</script>
<style scoped lang="scss">
.page {
min-width: 100vw;
min-height: 100vh;
}
</style>