溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

通過報錯問題了解Point事件的示例分析

發(fā)布時間:2021-07-12 11:51:14 來源:億速云 閱讀:182 作者:小新 欄目:web開發(fā)

這篇文章主要介紹了通過報錯問題了解Point事件的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

起因

從某個月黑風高的晚上開始,有人發(fā)現(xiàn)我們的 web-app 在 Chrome 模擬器里開始出現(xiàn)報錯,報錯信息大概就是下面這樣。

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

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

定位問題

根據(jù)調(diào)用棧很快定位到了代碼,源碼定位到之前一位同事寫的組件代碼,大概是這樣的:

dom.on('touchstart pointerdown', function (event) {
 /*部分業(yè)務代碼*/
 var touch = event.touches[0]; //報錯的地方
 /*部分業(yè)務代碼*/
})

debug 發(fā)現(xiàn)是觸發(fā)了 pointdown 事件,因為 event 沒有 touches 這個字段,導致拋出異常。但是之前用的好好的呀,難道是瀏覽器的 API 變化了?而且我也沒有了解過 pointerdown 事件,這個事件是用來處理什么的呢?于是我?guī)е鴥蓚€問題開啟了搜索之旅:

  • 什么是 pointerdown 事件

  • 為什么突然開始爆發(fā)錯誤

聊聊 pointer events

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

設備輸入形式的多樣化

在 PC 時代,我們通過鼠標與屏幕交互,這時候,我們設計系統(tǒng)時只需要考慮鼠標事件就好了。但是如今,有很多新的設備,比如智能手機,平板電腦,他們包含了其他的輸入方式,比如觸摸,手寫筆,官方也為這些輸入形式都提供了新的事件。

但是對于開發(fā)者來說,這是件很麻煩的事,因為這意味著你需要為你的網(wǎng)頁適配各種事件,比如你要根據(jù)用戶的移動來畫圖,你需要兼容 PC 和手機,你的代碼可能就會是下面這樣

dom.addEventListener('mousemove',
 draw);
dom.addEventListener('touchmove',
 draw);

如果需要兼容更多的輸入設備呢?比如手寫筆,這樣的話代碼就會很復雜。而且,為了兼容現(xiàn)有的基于鼠標事件的代碼,很多瀏覽器都會為所有的輸入類型觸發(fā)鼠標事件(例如在 touchmove 時觸發(fā) mousemove,我在 Chrome 試驗了一下不會觸發(fā),但是因為沒有設備,手寫筆的情況沒有試),這也會導致無法確認是否真的是鼠標觸發(fā)的事件。

如何兼容多種輸入形式

為了解決這一系列的問題,W3C 定義了一種新的輸入形式,即 pointer。任何由鼠標、觸摸、手寫筆或者其他輸入設備在屏幕上觸發(fā)的接觸,都算是 pointer 事件。

通過報錯問題了解Point事件的示例分析

它的 API 和鼠標事件很像,非常容易遷移。除了提供鼠標事件常用的屬性,比如 clientX,target 等等,還提供了一些用于其他輸入設備的屬性,比如壓力,接觸面,傾斜角度等等,這樣開發(fā)者就可以利用 pointer 事件為所有的輸入設備開發(fā)自己的功能了!

提供的屬性

pointer 事件提供了一些特有的事件屬性

  • pointerId:當前指針事件的唯一標識,主要是在多點觸控時標識唯一的一個輸入源

  • width:接觸面的寬度

  • height:接觸面的高度

  • pressure:接觸的壓力值,范圍是0-1,對于不支持壓力的硬件,比如鼠標,按壓時該值必須為 0.5,否則為 0

  • tiltX,titltY:手寫筆的角度

  • pointerType:事件類型,目前有 mouse,pen,touch,如果是無法探測的指針類型,則該值為空字符串

  • isPrimary:用于標識是否是主指針,主要是在多點觸控中生效,開發(fā)者也可以通過忽略非主指針的指針事件來實現(xiàn)單點觸控。

如何確定主指針:

鼠標輸入:一定是主指針

觸摸輸入:如果 pointerdown 觸發(fā)時沒有其他激活的觸摸事件,isPrimary 為 true

手寫筆輸入:與觸摸事件類似,pointerdown 觸發(fā)時沒有其他激活的 pointer 事件

相關事件

事件名稱作用
pointerover與 mouseover 行為一致
pointerenter與 mouseenter 行為一致
pointerdown指針進入活動狀態(tài),比如觸摸了屏幕,類似于 touchstart
pointermove指針進行了移動
pointerup指針取消活動狀態(tài),比如手指離開了屏幕,類似于 touchend
pointercancel類似于 touchcancel
pointerout指針離開元素邊緣或者離開屏幕,類似于 mouseout
pointerleave類似于 mouseleave
gotpointercapture元素捕獲到指針事件時觸發(fā)
lostpointercapture指針被釋放時觸發(fā)

可以看到,pointer 事件與已知的事件類型基本一致,但是有一點區(qū)別:在觸摸屏上,我們可能會滑動屏幕來觸發(fā)頁面滾動,縮放或者刷新,對于 touch 事件,這時會觸發(fā) touchmove,但是對于 pointer 事件,當觸發(fā)這些瀏覽器行為時,你卻會接收到 pointercancel 事件以便于通知你瀏覽器已經(jīng)接管了你的指針事件。

如何檢測

首先,pointer 事件的支持程度已經(jīng)很不錯了,你可以使用 Pointer Events polyfill (本地下載)來進行兼容,也可以自行檢測

if (window.PointerEvent) {
 // 支持
} else {
 // 不支持
}

導致問題的原因

這時候,對于本文一開始提到的問題就顯而易見了,因為 point events 是沒有 touches 這個屬性的。那么我們還有兩個問題。

為什么之前會用到 point events?

后來我看了下 zepto 的源碼,在事件處理時是考慮到了 point event 的,同事之前寫的代碼大概是參考了 zepto 的事件系統(tǒng)。

為什么會突然爆發(fā)這個問題?

很簡答,Chrome 55 開始支持這個 API,Chrome 具體的支持信息可以參考官方日志,至于怎么檢測瀏覽器支持,可以參考上面的內(nèi)容

感謝你能夠認真閱讀完這篇文章,希望小編分享的“通過報錯問題了解Point事件的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,更多相關知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI