早期浏览器很low,它只存在鼠标事件(MouseEvent)。随时代的发展出现了智能手机、平板电脑等触屏设备,交互方式发生了变化,单纯的鼠标事件已不够开发人员使用了。于是引入了触摸事件(TouchEvent)。不过这还不够完美,没有把触控笔事件考虑进去。当要求移动端、PC端同时具备拖拽功能时,开发人员还要维护两份事件逻辑。
为了解决上述问题,官方引入了全新的规范Pointer指针事件(Pointer) ,它提供了一套统一的事件,鼠标、触摸、触控笔事件一锅端了,不需要再维护两套事件逻辑。
Pointer指针事件属性
Pointer继承MouseEvent事件,因此常用属性clientX,clientY
等指针事件都具备,同时指针事件也扩展了它自己独有的属性。
属性 | 介绍 |
---|---|
pointerId | 指针引起的事件的唯一标识 |
width | 指针的接触面的CSS像素宽度 |
height | 指针的接触面的CSS像素高度 |
pressure | 指针输入的压力值,范围在0-1之间 |
tangentialPressure | 切向压力值,范围在-1-1]之间,0表示控制设备中立状态时的值 |
tiltX | 由输入设备(如手写笔)与Y轴的构成平面,和YZ平面之间的夹角,范围在-90-90之间 |
tiltY | 由输入设备(如手写笔)与X轴构成平面,和XZ平面之间的夹角,范围在-90-90之间 |
twist | 输入设备(如手写笔)围绕自身范围旋转的角度,范围在0-359之间 |
pointerType | 表示触发事件的设备类型,mouse,pen,touch |
isPrimary | 表示一个指针是否是当前设备类型的主指针 |
以上属性使用场景我没想到,有大佬的话可以指点下。
Pointer事件类型
Pointer有不同的事件类型,与鼠标事件一样有相同的语义话表示(down, up, move, over, out, enter, leave)。
事件类型 | 事件介绍 |
---|---|
pointerover | 当定点设备进入某个元素的命中检测 范围时触发。 |
pointerenter | 当定点设备进入某个元素或其子元素的命中检测范围时,或做为某一类不支悬停(hover)状态的设备所触发的poinerdown事件的后续事件时所触发。(详情可见 pointerdown事件类型). |
pointerdown | 当某指针得以激活时触发。 |
pointermove | 当某指针改变其坐标时触发。 |
pointerup | 当某指针不再活跃时触发。 |
pointercancel | 当浏览器认为某指针不会再生成新的后续事件时触发(例如某设备不再活跃) |
pointerout | 可能由若干原因触发该事件,包括:定位设备移出了某命中检测的边界;不支持悬浮状态的设备发生pointerup事件(见pointerup事件); 作为 pointercancel event事件的后续事件(见pointercancel事件);当数位板检测到数位笔离开了悬浮区域时。 |
pointerleave | 当定点设备移出某元素的命中检测边界时触发。对于笔形设备来说,当数位板检测到笔移出了悬浮范围时触发。 |
gotpointercapture | 当某元素接受到一个指针捕捉时触发。 |
lostpointercapture | 当针对某个指针的指针捕捉得到释放时触发。 |
指针、鼠标及触摸事件对比:
MouseEvent | TouchEvent | PointerEvent |
---|---|---|
mousedown | touchstart | pointerdown |
mousemove | touchmove | pointermove |
mouseup | touchend | pointerup |
touchcancel | pointercancel | |
mouseenter | pointerenter | |
mouseleave | pointerleave | |
mouseover | pointerover | |
mouseout | pointerout | |
gotpointercapture | ||
lostpointercapture |
Pointer事件的使用
先看看鼠标实现拖拽效果:
<div id="app"></div>
<script>
const app = document.getElementById('app')
let isPointerDown = false
app.addEventListener('mousedown', function (e) {
isPointerDown = true
});
document.addEventListener('mousemove', function (e) {
if (isPointerDown) {
const left = app.getBoundingClientRect().left
const top = app.getBoundingClientRect().top
let newLeft = e.clientX - left
let newTop = e.clientY - top
console.log(newLeft, newTop);
app.style.left = newLeft + left - app.clientWidth / 2 + 'px'
app.style.top = newTop + top - app.clientHeight / 2 + 'px'
}
});
document.addEventListener('mouseup', function (e) {
isPointerDown = false
});
</script>
电脑、移动设备分别访问链接,出现的效果是电脑可以拖拽,移动设备不支持。如果想要移动设备满足拖拽要单独使用触摸事件再写一套。
可以点击这里体验:https://code.juejin.cn/pen/7250291342034042940
用Pointer事件实现拖拽:
<div id="app"></div>
<script>
const app = document.getElementById('app')
let isPointerDown = false
app.addEventListener('pointerdown', function (e) {
isPointerDown = true
});
app.addEventListener('pointermove', function (e) {
//捕获
app.setPointerCapture(e.pointerId)
if (isPointerDown) {
const left = app.getBoundingClientRect().left
const top = app.getBoundingClientRect().top
let newLeft = e.clientX - left
let newTop = e.clientY - top
app.style.left = newLeft + left - app.clientWidth / 2 + 'px'
app.style.top = newTop + top - app.clientHeight / 2 + 'px'
}
});
app.addEventListener('pointerup', function (e) {
isPointerDown = false
});
</script>
Pointer事件与鼠标事件使用存在差异,Pointer使用setPointerCapture API做为捕获。
使用Pointer事件后电脑、移动设备都能进行拖拽。
可以点击这里体验: https://code.juejin.cn/pen/7250289016656887847
移动设备拖拽效果图:
总结
Pointer指针事件帮助我们通过一份代码,同时处理鼠标,触摸和触控笔事件,能为开发者节省掉时间。避免维护多套事件逻辑,做到一套事件逻辑两端跑。
如果我的文章对你有帮助,您的👍就是对我的最大支持_。
往期文章:http://linglan01.cn/about