从某个月黑风高的晚上开始,有人发现我们的web-app在Chrome模拟器里开始出现报错,报错信息大概就是下面这样。
VM1023:1UncaughtTypeError:Cannotreadproperty'0'ofundefined
定位问题
根据调用栈很快定位到了代码,源码定位到之前一位同事写的组件代码,大概是这样的:
什么是pointerdown事件
为什么突然开始爆发错误
聊聊pointerevents
查问题,最简单的问题就是搂一遍W3C的官方文档了。这里简单说下我的理解。
设备输入形式的多样化
在PC时代,我们通过鼠标与屏幕交互,这时候,我们设计系统时只需要考虑鼠标事件就好了。但是如今,有很多新的设备,比如智能手机,平板电脑,他们包含了其他的输入方式,比如触摸,手写笔,官方也为这些输入形式都提供了新的事件。
但是对于开发者来说,这是件很麻烦的事,因为这意味着你需要为你的网页适配各种事件,比如你要根据用户的移动来画图,你需要兼容PC和手机,你的代码可能就会是下面这样
如何兼容多种输入形式
为了解决这一系列的问题,W3C定义了一种新的输入形式,即pointer。任何由鼠标、触摸、手写笔或者其他输入设备在屏幕上触发的接触,都算是pointer事件。
它的API和鼠标事件很像,非常容易迁移。除了提供鼠标事件常用的属性,比如clientX,target等等,还提供了一些用于其他输入设备的属性,比如压力,接触面,倾斜角度等等,这样开发者就可以利用pointer事件为所有的输入设备开发自己的功能了!
提供的属性
pointer事件提供了一些特有的事件属性
pointerId:当前指针事件的唯一标识,主要是在多点触控时标识唯一的一个输入源
width:接触面的宽度
height:接触面的高度
pressure:接触的压力值,范围是0-1,对于不支持压力的硬件,比如鼠标,按压时该值必须为0.5,否则为0
tiltX,titltY:手写笔的角度
isPrimary:用于标识是否是主指针,主要是在多点触控中生效,开发者也可以通过忽略非主指针的指针事件来实现单点触控。
如何确定主指针:
鼠标输入:一定是主指针
触摸输入:如果pointerdown触发时没有其他激活的触摸事件,isPrimary为true
手写笔输入:与触摸事件类似,pointerdown触发时没有其他激活的pointer事件
可以看到,pointer事件与已知的事件类型基本一致,但是有一点区别:在触摸屏上,我们可能会滑动屏幕来触发页面滚动,缩放或者刷新,对于touch事件,这时会触发touchmove,但是对于pointer事件,当触发这些浏览器行为时,你却会接收到pointercancel事件以便于通知你浏览器已经接管了你的指针事件。
如何检测
首先,pointer事件的支持程度已经很不错了,你可以使用PointerEventspolyfill(本地下载)来进行兼容,也可以自行检测
这时候,对于本文一开始提到的问题就显而易见了,因为pointevents是没有touches这个属性的。那么我们还有两个问题。
为什么之前会用到pointevents?
为什么会突然爆发这个问题?
很简答,Chrome55开始支持这个API,Chrome具体的支持信息可以参考官方日志,至于怎么检测浏览器支持,可以参考上面的内容