首頁 >web前端 >js教程 >怎樣使用Point事件

怎樣使用Point事件

php中世界最好的语言
php中世界最好的语言原創
2018-05-29 10:32:263688瀏覽

這次帶給大家怎樣使用Point事件,使用Point事件的注意事項有哪些,以下就是實戰案例,一起來看一下。

前言

這篇文章在草稿箱裡躺了很久,因為最近又遇到了相關問題,於是又整理了一下。請注意這裡講的不是 css 的 pointer-events。下面話不都說了,來一起看看詳細的介紹吧。

起因

從某個月黑風高的晚上開始,有人發現我們的web-app 在Chrome 模擬器裡開始出現報錯,報錯訊息大概就是下面這樣。

VM1023:1 Uncaught TypeError: Cannot read property '0' of undefined

但是只有他的瀏覽器有問題,而且對功能毫無影響,本著在我的機器上不復現的精神(好吧,當時比較忙),這個問題的優先級排的不高,但是後面一段時間慢慢有人也出現相同的問題,於是我開始在意這個問題了。

定位問題

根據呼叫堆疊很快就定位到了程式碼,原始碼定位到之前一位同事寫的元件程式碼,大概是這樣的:

dom.on('touchstart pointerdown', function (event) {
 /*部分业务代码*/
 var touch = event.touches[0]; //报错的地方
 /*部分业务代码*/
})

debug 發現是觸發了pointdown 事件,因為event 沒有touches 這個字段,導致拋出異常。但是之前用的好好的呀,難道是瀏覽器的 API 變化了?而且我也沒了解 pointerdown 事件,這事件是用來處理什麼的呢?於是我帶著兩個問題開啟了搜尋之旅:

  • 什麼是pointerdown 事件

  • 為什麼突然開始爆發錯誤

聊聊pointer events

查詢問題,最簡單的問題就是摟一遍W3C 的官方文件了。這裡簡單說下我的理解。

裝置輸入形式的多樣化

在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 {
 // 不支持
}

导致问题的原因

这时候,对于本文一开始提到的问题就显而易见了,因为 point events 是没有 touches 这个属性的。那么我们还有两个问题。

为什么之前会用到 point events?

后来我看了下 zepto 的源码,在事件处理时是考虑到了 point event 的,同事之前写的代码大概是参考了 zepto 的事件系统。

为什么会突然爆发这个问题?

很简答,Chrome 55 开始支持这个 API,Chrome 具体的支持信息可以参考官方日志,至于怎么检测浏览器支持,可以参考上面的内容

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样使用Vue中字符串模板

如何处理Mac安装thrift因bison报错

以上是怎樣使用Point事件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn