1. touch 事件简介
- touchstart 事件:当手指触摸屏幕时候触发,即使已经有一个手指放在屏幕上也会触发;
- touchmove 事件:当手指在屏幕上滑动的时候连续地触发。在这个事件发生期间,调用 preventDefault() 事件可以阻止滚动;
- touchend 事件:在用户从元素上移开手指时会发生。
- touchcancel 事件:在触摸事件被中断时发生。不同的设备会在不同的动作中中断触摸事件,如果发生这种“错误”,那么包含此事件来清理代码被认为是一种好习惯。
每个触摸事件被触发后会生成一个 event 对象,event 对象里额外包括以下三个触摸列表
名称 | 含义 |
---|---|
touches | 当前屏幕上所有触摸点的列表 |
targetTouches | 当前对象上所有触摸点的列表; |
changedTouches | 涉及当前(引发)事件的触摸点的列表; |
举例区分触摸事件中的这三个属性:
1. 用一个手指接触屏幕,触发事件,此时这三个属性有相同的值。
2. 用第二个手指接触屏幕,此时,touches 有两个元素,每个手指触摸点为一个值。
当两个手指触摸相同元素时,targetTouches 和 touches 的值相同,否则 targetTouches 只有一个值。
changedTouches 此时只有一个值,为第二个手指的触摸点,因为第二个手指是引发事件的原因。
3. 用两个手指同时接触屏幕,此时 changedTouches 有两个值,每一个手指的触摸点都有一个值
4. 手指滑动时,三个值都会发生变化
5. 一个手指离开屏幕,touches 和 targetTouches 中对应的元素会同时移除,而 changedTouches 仍然会存在元素。
6. 手指都离开屏幕之后,touches 和 targetTouches 中将不会再有值,changedTouches 还会有一个值,
此值为最后一个离开屏幕的手指的接触点。
触摸列表里每次触摸由 touch 对象组成(包含触摸信息)主要属性如下:
属性 | 含义 |
---|---|
clientX | 触点相对于可见视区 (visual viewport) 左边沿的的 X 坐标. 不包括任何滚动偏移. 只读属性. |
clientY | 触点相对于可见视区 (visual viewport) 上边沿的的 Y 坐标. 不包括任何滚动偏移. 只读属性. |
pageX | 触点相对于 HTML 文档左边沿的的 X 坐标. 当存在水平滚动的偏移时, 这个值包含了水平滚动的偏移. 只读属性. |
pageY | 触点相对于 HTML 文档上边沿的的 Y 坐标. 当存在水平滚动的偏移时, 这个值包含了垂直滚动的偏移. 只读属性. |
screenX | 触点相对于屏幕左边沿的的 X 坐标. 只读属性. |
screenY | 触点相对于屏幕上边沿的的 Y 坐标. 只读属性. |
radiusX | 能够包围用户和触摸平面的接触面的最小椭圆的水平轴 (X轴) 半径. 这个值的单位和 screenX 相同. 只读属性. |
radiusY | 能够包围用户和触摸平面的接触面的最小椭圆的垂直轴 (Y轴) 半径. 这个值的单位和 screenY 相同. 只读属性. |
rotationAngle | 它是这样一个角度值:由 radiusX 和 radiusY 描述的正方向的椭圆,需要通过顺时针旋转这个角度值,才能最精确地覆盖住用户和触摸平面的接触面. 只读属性. |
force | 手指挤压触摸平面的压力大小, 从 0.0(没有压力) 到 1.0(最大压力) 的浮点数. 只读属性. |
target | 当这个触点最开始被跟踪时(在 touchstart 事件中), 触点位于的HTML元素.。哪怕在触点移动过程中, 触点的位置已经离开了这个元素的有效交互区域, 或者这个元素已经被从文档中移除。注意:如果这个元素在触摸过程中被移除, 这个事件仍然会指向它, 但是不会再冒泡这个事件到 window 或 document 对象。 因此,如果有元素在触摸过程中可能被移除, 最佳实践是将触摸事件的监听器绑定到这个元素本身, 防止元素被移除后, 无法再从它的上一级元素上侦测到从该元素冒泡的事件。只读属性. |
identifier | Touch 对象的唯一标识符. 一次触摸动作在平面上移动的整个过程中, 该标识符不变. 可以根据它来判断跟踪的是否是同一次触摸过程。 只读属性. |
2. Vue中 使用 touch 事件简单案例
效果:
完整代码:
<template>
<div class="test">
<div class="wrap">
背景区
<div class="animate__animated animate__zoomIn insert" v-if="showDeviceImg">插入图形</div>
</div>
<div class="drawer" ref="drawer">触摸滑动区域</div>
</div>
</template>
<script>
export default {
data() {
return {
showDeviceImg:false,
startY: 0,
endY:0,
};
},
methods: {
handleTounchListener() {
this.$refs.drawer.addEventListener('touchstart', (event) => {
// 获取触摸初始 Y 坐标
console.log(event)
this.startY = event.targetTouches[0].pageY;
})
this.$refs.drawer.addEventListener('touchmove', (event) => {
// 若两个接触点,return
if (event.targetTouches.length > 1){ return }
this.endY = event.targetTouches[0].pageY;
const distance = this.endY - this.startY; // 计算起止位置纵坐标差值
if(distance > 60){
// 向下滑动
this.showDeviceImg = true;
}else if(distance < -60){
// 向上滑动
this.showDeviceImg = false;
}
event.preventDefault(); // 阻止默认滚动
})
this.$refs.drawer.addEventListener('touchend', (event) => {
console.log('touchEnd',event.targetTouches)
})
this.$refs.drawer.addEventListener('touchcancel', (event) => {
console.log('touchCancel', event)
})
},
},
mounted() {
this.handleTounchListener()
},
};
</script>
<style lang="stylus" scoped>
.test {
font-size: 25px;
text-align: center;
.wrap{
width: 100%;
min-height: 10vh;
background-color: red;
.insert{
width: 100%;
height: 30vh;
background-color: green;
}
}
.drawer{
width: 100%;
height: 100vh;
background-color: pink;
}
}
</style>