成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從一次報(bào)錯(cuò)聊聊 Point 事件

quietin / 2590人閱讀

摘要:定位問(wèn)題根據(jù)調(diào)用棧很快定位到了代碼,源碼定位到之前一位同事寫(xiě)的組件代碼,大概是這樣的部分業(yè)務(wù)代碼報(bào)錯(cuò)的地方部分業(yè)務(wù)代碼發(fā)現(xiàn)是觸發(fā)了事件,因?yàn)闆](méi)有這個(gè)字段,導(dǎo)致拋出異常。它的和鼠標(biāo)事件很像,非常容易遷移。

同步自我的博客,歡迎交流

這篇文章在草稿箱里躺了很久,因?yàn)樽罱钟龅搅讼嚓P(guān)問(wèn)題,于是又整理了一下。請(qǐng)注意這里講的不是 csspointer-events。

起因

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

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

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

定位問(wèn)題

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

dom.on("touchstart  pointerdown", function (event) {
        /*部分業(yè)務(wù)代碼*/
        
        var touch = event.touches[0]; //報(bào)錯(cuò)的地方
        
        /*部分業(yè)務(wù)代碼*/
})

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

什么是 pointerdown 事件

為什么突然開(kāi)始爆發(fā)錯(cuò)誤

聊聊 pointer events

查問(wèn)題,最簡(jiǎn)單的問(wèn)題就是摟一遍 W3C 的官方文檔了。這里簡(jiǎn)單說(shuō)下我的理解。

設(shè)備輸入形式的多樣化

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

但是對(duì)于開(kāi)發(fā)者來(lái)說(shuō),這是件很麻煩的事,因?yàn)檫@意味著你需要為你的網(wǎng)頁(yè)適配各種事件,比如你要根據(jù)用戶的移動(dòng)來(lái)畫(huà)圖,你需要兼容 PC 和手機(jī),你的代碼可能就會(huì)是下面這樣

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

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

如何兼容多種輸入形式

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

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

提供的屬性

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

pointerId:當(dāng)前指針事件的唯一標(biāo)識(shí),主要是在多點(diǎn)觸控時(shí)標(biāo)識(shí)唯一的一個(gè)輸入源

width:接觸面的寬度

height:接觸面的高度

pressure:接觸的壓力值,范圍是0-1,對(duì)于不支持壓力的硬件,比如鼠標(biāo),按壓時(shí)該值必須為 0.5,否則為 0

tiltX,titltY:手寫(xiě)筆的角度

pointerType:事件類(lèi)型,目前有 mouse,pen,touch,如果是無(wú)法探測(cè)的指針類(lèi)型,則該值為空字符串

isPrimary:用于標(biāo)識(shí)是否是主指針,主要是在多點(diǎn)觸控中生效,開(kāi)發(fā)者也可以通過(guò)忽略非主指針的指針事件來(lái)實(shí)現(xiàn)單點(diǎn)觸控。
如何確定主指針:

鼠標(biāo)輸入:一定是主指針

觸摸輸入:如果 pointerdown 觸發(fā)時(shí)沒(méi)有其他激活的觸摸事件,isPrimarytrue

手寫(xiě)筆輸入:與觸摸事件類(lèi)似,pointerdown 觸發(fā)時(shí)沒(méi)有其他激活的 pointer 事件

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

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

如何檢測(cè)

首先,pointer 事件的支持程度已經(jīng)很不錯(cuò)了,你可以使用 Pointer Events polyfill來(lái)進(jìn)行兼容,也可以自行檢測(cè)

if (window.PointerEvent) {
    // 支持
} else {
  // 不支持
}
導(dǎo)致問(wèn)題的原因

這時(shí)候,對(duì)于本文一開(kāi)始提到的問(wèn)題就顯而易見(jiàn)了,因?yàn)?point events 是沒(méi)有 touches 這個(gè)屬性的。那么我們還有兩個(gè)問(wèn)題。

為什么之前會(huì)用到 point events

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

為什么會(huì)突然爆發(fā)這個(gè)問(wèn)題?

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

總結(jié)

對(duì)于開(kāi)發(fā)來(lái)說(shuō),一定要鉆進(jìn)去,任何 bug 都是有原因的

代碼報(bào)錯(cuò)應(yīng)該有相應(yīng)的監(jiān)控機(jī)制,讓機(jī)器來(lái)幫我們發(fā)現(xiàn)問(wèn)題,而不是靠人工去干預(yù)

參考
https://www.w3.org/Submission...
https://developers.google.com...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82984.html

相關(guān)文章

  • 有關(guān)array_keys,array_merge的一報(bào)錯(cuò)

    摘要:類(lèi)型不同導(dǎo)致的問(wèn)題結(jié)果如下我們發(fā)現(xiàn)當(dāng)為數(shù)字的時(shí)候,是不會(huì)進(jìn)行去重的導(dǎo)致的類(lèi)型轉(zhuǎn)換結(jié)果我們發(fā)現(xiàn)通過(guò)之后都變成了類(lèi)型 array_merge 類(lèi)型不同導(dǎo)致的問(wèn)題 $a = [1=>php,2=>mysql,3=>redis]; $c = [1=>zabbix,2=>mysql]; $d = array_merge($a,$c); var_dump($d); 結(jié)果如下 array(5) {...

    huashiou 評(píng)論0 收藏0
  • 記Yii鏈接MySQL[2002]的一報(bào)錯(cuò)

    摘要:解決開(kāi)發(fā)使用的是的框架,在中配置的是然而,在中,通過(guò)發(fā)現(xiàn)的有兩個(gè)用戶的紀(jì)錄,一個(gè)是,另一個(gè)是空,即當(dāng)使用的用戶是非時(shí),訪問(wèn)的是時(shí),就會(huì)報(bào)這個(gè)錯(cuò)。解決辦法將修改為。。,的,只不過(guò)的配置導(dǎo)致了不同的結(jié)果。 SQLSTATE[HY000] [2002] No such file or directory 解決Trace 開(kāi)發(fā)使用的是PHP的Yii2框架,在config/db.php中配置的h...

    wenshi11019 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<