鼠标事件之外,认识一下指针事件家族?
theme: channing-cyan
highlight: a11y-dark
我正在参加「掘金·启航计划」
鼠标事件之外,认识一下指针事件家族?
一、前言
相信大多数开发者,都知道或用过鼠标事件,例如 mousedown 和 mouseup,而指针事件家族,例如 pointerdown 和 pointerup,用到的人则相对比较少了。
我是因为遇到:需要把鼠标事件重新定向到特定元素,从而实现捕获鼠标绑定到特定元素的需求,用到了 setCapture(),而 setCapture 已经被弃用且是非标准的,然后选用了 setPointerCapture。不得了,一下子捅了 PointerEvent 指针事件家族的马蜂窝。
以实现“拖动边界线改变布局”为例,用了 setPointerCapture 就得用 releasePointerCapture,而在实现需求过程中,还会接着使用 pointerdown、pointermove以及pointerup。
本文,将以实现“滑块”和“拖动边界线改变布局”的需求为例,以 setPointerCapture 的使用为引,介绍:
1、MouseEvent 和 PointerEvent 家族的介绍
2、简述 setCapture 和 setPointerCapture
3、PointerEvent 的应用场景
二、MouseEvent 和 PointerEvent 家族的介绍
2.1 MouseEvent 家族
MouseEvent 接口指用户与指针设备(如鼠标)交互时发生的事件。使用此接口的常见事件包括:click、dblclick、mouseup、mousedown。
MouseEvent 派生自 UIEvent,UIEvent 派生自 Event。虽然 MouseEvent.initMouseEvent() 方法保持向后兼容性,但是应该使用 MouseEvent() 构造函数创建一个 MouseEvent 对象。
一些具体的事件都派生自 MouseEvent:WheelEvent 和DragEvent。
它的一些相关事件:
- setCapture 用于把全部的鼠标事件重新定向到指定元素。
- releaseCapture 用来将鼠标从先前通过 setCapture() 绑定的元素身上释放出来。
- mousedown 事件在定点设备(如鼠标或触摸板)按钮在元素内按下时,会在该元素上触发。
- mouseenter 事件在定点设备(通常指鼠标)首次移动到元素的激活区域内时,在该元素上触发。
- mouseleave 事件在定点设备(通常是鼠标)的指针移出某个元素时被触发。
- mousemove 事件在定点设备(通常指鼠标)的光标在元素内移动时,会在该元素上触发。
- mouseout 事件在定点设备(通常是鼠标)移动至元素或其子元素之外时,会在该元素上触发。
- mouseover 当一个定点设备(通常指鼠标)在一个元素本身或者其子元素上移动时,mouseover 事件在该元素上触发。
- mouseup 事件在定点设备(如鼠标或触摸板)按钮在元素内释放时,在该元素上触发。
2.2 PointerEvent 家族
PointerEvent 接口代表了由 指针 引发的 DOM 事件的状态,包括接触点的位置,引发事件的设备类型,接触表面受到的压力等。
指针 是输入设备的硬件层抽象(比如鼠标,触摸笔,或触摸屏上的一个触摸点)。指针 能指向一个具体表面(如屏幕)上的一个(或一组)坐标。
指针的 击中检测 指浏览器用来检测 指针事件的目标元素的过程。大多数情况下,这个目标元素是由 指针的位置和元素在文章中的位置和分层共同决定的。
该接口属性继承自 MouseEvent 和 Event,所以它们有很多相似的属性和方法,只是 PointerEvent 的作用对象更具体,具体到鼠标指针。
它的一些相关事件:
- setPointerCapture 用于将特定元素指定为未来指针事件的捕获目标。
- releasePointerCapture 用来将鼠标指针从先前通过 setPointerCapture() 绑定的元素身上释放出来,还给鼠标指针自由。
- pointerdown 鼠标指针按下时触发该事件
- pointerenter 鼠标指针首次进入到元素的激活区域内时触发该事件
- pointerleave 鼠标指针离开时触发该事件
- pointermove 鼠标指针移动时触发该事件
- pointerout 鼠标指针移动到元素之外时触发该事件
- pointerover 鼠标指针悬浮覆盖时触发该事件
- pointerup 鼠标指针抬起时触发该事件
三、简述 setCapture 和 setPointerCapture
3.1 特征比较
| | setCapture | setPointerCapture | |------------| --------- | --------- | | 是否标准规范中的特性 | 否 | 是 | | 是否已废弃 | 是 | 否 | | 浏览器兼容性 | 好 | 差 | | 配套对应事件 | releaseCapture | releasePointerCapture |
3.2 setCapture 和 setPointerCapture
在处理一个 mousedown 事件过程中调用 setCapture() 方法来把全部的鼠标事件重新定向到这个元素,直到鼠标按钮被释放或者 document.releaseCapture() 被调用。
// 语法 js // retargetToElement 如果被设置为 true, 所有事件被直接定向到这个元素; 如果是 false, 事件也可以在这个元素的子元素上触发。 element.setCapture(retargetToElement);
setPointerCapture() 方法用于将特定元素指定为未来指针事件的捕获目标。指针的后续事件将以捕获元素为目标,直到捕获被释放(通过Element.releasePointerCapture())。
// 语法 js // pointerId 是指 PointerEvent 对象的 pointerId element.setPointerCapture(pointerId);
注意: 一旦设置了 pointer capture,pointerover、pointerout、pointerenter 和 pointerleave 事件将不会被触发,直到越过设置了 capture 的元素的边界。 这是因为其他元素将不能再作为 pointer 事件的目标了。这会影响到这些事件在其他元素上的触发。
四、PointerEvent 的应用场景
4.1 PointerEvent 应用场景简述
把全部的鼠标事件重新定向到特定元素,常见有 setCapture 和 setPointerCapture,但是 setCapture 是非标准的,那意味着在一些浏览器可能会不被支持, 而且它又被废弃了,所以 setPointerCapture 通常成为了首选。而常见与之配套使用的 PointerEvent 中的事件有 onpointerdown、onpointermove、onpointerup 以及 releasePointerCapture。
setPointerCapture 的应用场景,或者说把全部的鼠标事件重新定向到特定元素的需求场景,挺常见的,只是通常被封装在了组件里面。例如: 1、滑块组件,拖动滑盖,可视化显示拖动结果,例如一个数值或百分比。
2、滑块校验组件,拖动滑块复位,常用于人机验证场景。
3、拖动边界线改变布局,左右拖动改变左右的元素的宽,这种需求非常常见,也非常常用,而且在各种终端都是。
4、其他:其实和鼠标以及鼠标指针有关的动作效果、动画效果、操作行为,PointerEvent 都有很广的应用场景,尤其在游戏领域中。
4.2 PointerEvent 案例:实现滑块
下面是一个 PointerEvent 实现滑块的示例 Demo,Demo 中,使用了 PointerEvent 中的:
①onpointerdown
②onpointermove
③onpointerup
④setPointerCapture
⑤releasePointerCapture
```html
滑块拖动 setPointerCapture 示例 Demo
在小小的滑槽里,滑呀滑呀滑
```
Demo 效果图:
4.3 PointerEvent 案例:拖动边界线改变布局
这是一个通过拖动边界线改变宽度,从而改变布局的 Demo,Demo 中,使用了 PointerEvent 中的:
①onpointerdown
②onpointermove
③onpointerup
④setPointerCapture
⑤releasePointerCapture
```html