设备输入形式的多样化
在 PC 时代,我们通过鼠标与屏幕交互,这时候,我们设计系统时只需要考虑鼠标事件就好了。但是如今,有很多新的设备,比如智能手机,平板电脑,他们包含了其他的输入方式,比如触摸,手写笔,官方也为这些输入形式都提供了新的事件。
但是对于开发者来说,这是件很麻烦的事,因为这意味着你需要为你的网页适配各种事件,比如你要根据用户的移动来画图,你需要兼容 PC 和手机,你的代码可能就会是下面这样
dom.addEventListener('mousemove', draw); dom.addEventListener('touchmove', draw);
如果需要兼容更多的输入设备呢?比如手写笔,这样的话代码就会很复杂。而且,为了兼容现有的基于鼠标事件的代码,很多浏览器都会为所有的输入类型触发鼠标事件(例如在 touchmove
时触发 mousemove
,我在 Chrome 试验了一下不会触发,但是因为没有设备,手写笔的情况没有试),这也会导致无法确认是否真的是鼠标触发的事件。
如何兼容多种输入形式
为了解决这一系列的问题,W3C 定义了一种新的输入形式,即 pointer
。任何由鼠标、触摸、手写笔或者其他输入设备在屏幕上触发的接触,都算是 pointer
事件。
它的 API 和鼠标事件很像,非常容易迁移。除了提供鼠标事件常用的属性,比如 clientX
,target
等等,还提供了一些用于其他输入设备的属性,比如压力,接触面,倾斜角度等等,这样开发者就可以利用 pointer
事件为所有的输入设备开发自己的功能了!
提供的属性
pointer 事件提供了一些特有的事件属性
-
pointerId:当前指针事件的唯一标识,主要是在多点触控时标识唯一的一个输入源
-
width:接触面的宽度
-
height:接触面的高度
-
pressure:接触的压力值,范围是0-1,对于不支持压力的硬件,比如鼠标,按压时该值必须为 0.5,否则为 0
-
tiltX,titltY:手写笔的角度
-
pointerType:事件类型,目前有
mouse
,pen
,touch
,如果是无法探测的指针类型,则该值为空字符串 -
isPrimary:用于标识是否是主指针,主要是在多点触控中生效,开发者也可以通过忽略非主指针的指针事件来实现单点触控。
如何确定主指针:-
鼠标输入:一定是主指针
-
触摸输入:如果
pointerdown
触发时没有其他激活的触摸事件,isPrimary
为true
-
手写笔输入:与触摸事件类似,
pointerdown
触发时没有其他激活的pointer
事件
-
相关事件
事件名称 | 作用 |
---|---|
pointerover | 与 mouseover 行为一致 |
pointerenter | 与 mouseenter 行为一致 |
pointerdown | 指针进入活动状态,比如触摸了屏幕,类似于 touchstart |
pointermove | 指针进行了移动 |
pointerup | 指针取消活动状态,比如手指离开了屏幕,类似于 touchend |
pointercancel | 类似于 touchcancel |
pointerout | 指针离开元素边缘或者离开屏幕,类似于 mouseout |
pointerleave | 类似于 mouseleave |
gotpointercapture | 元素捕获到指针事件时触发 |
lostpointercapture | 指针被释放时触发 |
可以看到,pointer
事件与已知的事件类型基本一致,但是有一点区别:在触摸屏上,我们可能会滑动屏幕来触发页面滚动,缩放或者刷新,对于 touch
事件,这时会触发 touchmove
,但是对于 pointer
事件,当触发这些浏览器行为时,你却会接收到 pointercancel
事件以便于通知你浏览器已经接管了你的指针事件。
如何检测
首先,pointer
事件的支持程度已经很不错了,你可以使用 Pointer Events polyfill来进行兼容,也可以自行检测
if (window.PointerEvent) { // 支持 } else { // 不支持 }