封装手势库
今天封装了一个手势库,使用了 Pointer events 指针事件,指针事件是一类可以为定点设备所触发的 DOM 事件。它们被用来创建一个可以有效掌握各类输入设备(鼠标、触控笔和单点或多点的手指触摸)的统一的 DOM 事件模型。
封装思路
Pointer events具有一个名为pointermove的事件,它和touchEvent的touchmove非常相似,但它可以接受更多的设备,我通过手指移动的坐标算出x轴投影和y轴投影,根据大小判断是向哪个方向移动。
核心代码
if (Math.abs(x) > MIN_SWIPE_DISTANCE || Math.abs(y) > MIN_SWIPE_DISTANCE) {
if (Math.abs(x) > Math.abs(y)) {
e._swipeDirection = x > 0 ? 'right' : 'left';
} else {
e._swipeDirection = y > 0 ? 'down' : 'up';
}
if (this.options.swipe) {
this.options.swipe(e);
}
}
// 首次点击
if (this.tapCount === 1) {
// 按住500ms触发长按事件
this.longTapTimeout = setTimeout(() => {
this.tapCount = 0;
if (this.options.longTap) {
this.options.longTap(e);
}
}, 500);
}
// 根据偏移距离判断是不是长按
const current1 = { x: e.clientX, y: e.clientY };
this.distance.x = current1.x - this.point.x;
this.distance.y = current1.y - this.point.y;
// 偏移量大于10表示移动
console.log(this.distance);
if (Math.abs(this.distance.x) > 10 || Math.abs(this.distance.y) > 10) {
this.tapCount = 0;
clearTimeout(this.longTapTimeout);
}
遇到的bug
当在移动端使用时,发现移动的距离不发生改变,设置touch-action: none;,发生的原因是:使用 Pointer_events 的应用程序将在浏览器开始处理触摸手势时收到一个 pointercancel (en-US) 事件。通过明确指定浏览器应该处理哪些手势,应用程序可以在 pointermove 和 pointerup (en-US) 监听器中为其余的手势提供自己的行为。使用 Touch_events 的应用程序通过调用 preventDefault() 禁用浏览器处理手势,但也应使用触摸操作确保浏览器在调用任何事件侦听器之前,了解应用程序的意图。
当手势开始时,浏览器与触摸的元素及其所有祖先的触摸动作值相交直到一个实现手势(换句话说,第一个包含滚动元素)的触摸动作值。这意味着在实践中,触摸动作通常仅适用于具有某些自定义行为的单个元素,而无需在该元素的任何后代上明确指定触摸动作。手势开始之后,触摸动作值的更改将不会对当前手势的行为产生任何影响。