Touch 触摸事件:
Touch 触摸事件是由苹果推出的。
特征检测:
判断浏览器是否支持 Touch 触摸事件。
if ('ontouchstart' in window) {
console.log('支持')
}
事件类型:
- touchsatrt:当手指触摸开始时触发。
- touchmove:当手指滑动时连续触发。
- touchend:当手指触摸结束时触发。
- touchcancel:当手指触摸中断时触发(例如:有来电、有弹框弹出等)。
触发了 touchend,就不会再触发 touchcancel;触发了 touchcancel,就不会再触发 touchend。所以,一般结束时要执行的方法,在 touchend 和 touchcancel 中都需要绑定。
const box = document.getElementById('box')
// 用手指在屏幕上点击一下,会触发一次 touchsatrt,一次 touchend
box.addEventListener('touchsatrt', () => {console.log('touchsatrt')})
box.addEventListener('touchend', () => {console.log('touchend')})
事件对象:
事件对象 Event 的常见属性:
-
type:事件类型。
-
target:目标元素。
-
touches:屏幕上所有的触摸点组成的类数组。
targetTouches:目标元素上所有的触摸点组成的类数组。
changeTouches:目标元素上状态发生了改变的触摸点组成的类数组。es 为复数,表明不单支持单指触摸,也支持多指触摸。
例如:以下为一个手机屏幕,在红色背景的元素上绑定了触摸事件。
用三根手指触摸屏幕,落在红色背景的元素中两根,其他区域一根。此时,touches 中有三个触摸点,targetTouches 中有两个触摸点,changeTouches 中有两个触摸点。
其他手指不动,中间那根手指向右滑动了一下。此时,touches 中有三个触摸点,targetTouches 中有两个触摸点,changeTouches 中有一个触摸点,就是滑动了的那根手机的触摸点。
触摸点:
组成 touches、targetTouches、changeTouches 类数组的 touch 对象就是触摸点。
// 单个触摸点
console.log(event.changeTouches[0])
触摸点的常见属性:
- identifier:触摸点的 id,唯一标识符。一般多指触摸时有用。
- target:目标元素。
- screenX、screenY:相对于屏幕左上角的坐标。
- clientX、clientY:相对于可视区域左上角的坐标。
- pageX、pageY:相对于页面左上角的坐标。
实现单指拖拽:
.box {
width: 200px;
height: 200px;
background-color: red;
}
<div id="box" class="box"></div>
const drag = $el => {
const startPoint = {}
const movePoint = {}
const currPos = {
x: 0,
y: 0,
}
const touchStartHanlder = e => {
e.preventDefault()
const touch = e.changedTouches[0]
startPoint.x = touch.pageX
startPoint.y = touch.pageY
}
const touchMoveHanlder = e => {
const touch = e.changedTouches[0]
movePoint.x = currPos.x + touch.pageX - startPoint.x
movePoint.y = currPos.y + touch.pageY - startPoint.y
$el.style.transform = `translate3d(${movePoint.x}px, ${movePoint.y}px, 0)`
}
const touchEndHanlder = () => {
currPos.x = movePoint.x
currPos.y = movePoint.y
}
// touch 事件是有内定顺序的,只有触发了 touchstart 之后,才会有 touchmove,,然后才会有 touchend 或者 touchcancel,所以可以并排写
$el.addEventListener('touchstart', touchStartHanlder, false)
$el.addEventListener('touchmove', touchMoveHanlder, false)
$el.addEventListener('touchend', touchEndHanlder, false)
$el.addEventListener('touchcancel', touchEndHanlder, false)
}
drag(document.getElementById('box'))
Pointer 指针事件:
Pointer 指针事件是由微软推出的,统一了鼠标、手指触摸和笔的事件。
Touch 触摸事件只会在移动端触发,不会在 PC 端触发。
Pointer 指针事件、mouseover/click 鼠标事件在移动端和 PC 端都会触发。
特征检测:
判断浏览器是否支持 Pointer 指针事件。
if ('onpointerdown' in window) {
console.log('支持')
}
事件类型:
Pointer 指针事件直接继承了鼠标事件,在鼠标事件的基础上又添加了一些其他内容,处理 Pointer 指针事件和处理鼠标事件几乎一致。
- pointerdown:指针按下时触发。
- pointermove:指针移动时触发。
- pointerup:指针松开时触发。
- pointercancel:指针中断时触发。
- pointerenter:指针进入目标元素及其后代元素区域时触发。 不支持事件冒泡。
- pointerleave:指针离开目标元素及其后代元素区域时触发。 不支持事件冒泡。
- pointerover:指针进入目标元素区域时触发。 支持事件冒泡。
- pointerout:指针离开目标元素区域时触发。支持事件冒泡。
事件对象:
事件对象 Event 的常见属性:
- type:事件类型。
- pointerType:指针类型(手指触摸/鼠标/笔等)。
- target:目标元素。
- pointerId:指针 id,唯一标识符。
- screenX、screenY:相对于屏幕左上角的坐标。
- clientX、clientY:相对于可视区域左上角的坐标。
- pageX、pageY:相对于页面左上角的坐标。
实现单指拖拽:
.box {
width: 200px;
height: 200px;
background-color: red;
}
<div id="box" class="box"></div>
const drag = $el => {
const startPoint = {}
const movePoint = {}
const currPos = {
x: 0,
y: 0,
}
const pointerMoveHanlder = e => {
movePoint.x = currPos.x + e.pageX - startPoint.x
movePoint.y = currPos.y + e.pageY - startPoint.y
$el.style.transform = `translate3d(${movePoint.x}px, ${movePoint.y}px, 0)`
}
const pointerUpHanlder = () => {
currPos.x = movePoint.x
currPos.y = movePoint.y
document.removeEventListener('pointermove', pointerMoveHanlder, false)
document.removeEventListener('pointerup', pointerUpHanlder, false)
document.removeEventListener('pointercancel', pointerUpHanlder, false)
}
// PC 端鼠标不按下去也会触发 pointermove,所以必须在 pointerdown 的事件处理函数中进行绑定,也就是必须先按下鼠标,才执行拖动、释放等方法
const pointerDownHanlder = e => {
startPoint.x = e.pageX
startPoint.y = e.pageY
// 拖拽之后,元素移动到新的位置,这之间是有时间差的,就会导致触摸点移出目标元素,触摸点移出目标元素后,pointermove 不会再触发,因此,需要将事件处理函数绑定在 document 上
document.addEventListener('pointermove', pointerMoveHanlder, false)
document.addEventListener('pointerup', pointerUpHanlder, false)
document.addEventListener('pointercancel', pointerUpHanlder, false)
}
$el.addEventListener('pointerdown', pointerDownHanlder, false)
// 不加这行代码来阻止移动端的默认事件,移动端将无法拖拽
$el.addEventListener('touchstart', e => {e.preventDefault()}, false)
}
drag(document.getElementById('box'))
touch-action
:
touch-action
:是一个 CSS 属性,用于设置移动端触摸操作时浏览器的行为。属性值有:
-
auto:默认值。完全由浏览器自己决定。
-
none:禁止默认的拖拽行为。
-
manipulation:只允许进行滚动和持续缩放,禁止双击缩放。
这个设置可以完美解决移动端 click 事件 300ms 延时的问题。
-
pan-x
:仅支持横向的默认拖拽行为(禁止纵向的默认拖拽行为)。 -
pan-y
:仅支持纵向的默认拖拽行为(禁止横向的默认拖拽行为)。 -
pan-up
:仅支持从上往下的默认拖拽行为(禁止从下往上、横向的默认拖拽行为)。
-
pan-down
:仅支持从下往上的默认拖拽行为(禁止从上往下、横向的默认拖拽行为)。 -
pan-left
:仅支持从左往右的默认拖拽行为(禁止从右往左、纵向的默认拖拽行为)。 -
pan-right
:仅支持从右往左的默认拖拽行为(禁止从左往右、纵向的默认拖拽行为)。
.box {
touch-action: manipulation;
}