摘要:把事件統一起來處理用戶的輸入要用到事件。就這樣,提取了鼠標觸摸屏觸控筆的共通之處,以方便開發跨設備的應用。雖然是一個抽象,但它包含了鼠標觸摸屏觸控筆的全部內容。手指與觸摸屏的屏幕接觸著,認定為。
跨設備的問題
平時我們在電腦上訪問的網頁,大部分情況下是用鼠標來控制的。比如說鏈接跳轉,就是鼠標指針移動到鏈接文字或圖片的位置,然后點擊一下。又比如說滾動屏幕,滑動一下鼠標滾輪就可以。
如果是供手機訪問的網頁呢?這時候的控制就靠觸摸屏了。鏈接跳轉就是用手指點上去,滾動屏幕則是手指按在屏幕上動一動。
因為是不同的設備(電腦、手機),所以盡管在瀏覽網頁時是類似的控制需求(鏈接跳轉、滾動屏幕),但就會有不同的交互形式。這些交互形式,也是由設備所能提供的輸入方式(鼠標、觸摸屏)決定的。
現在流行的響應式設計的網頁,追求的是只用一套代碼,也保證網頁在不同屏幕尺寸的設備上都具有較好的外觀。然而,這里的不同設備,可能不僅僅只是差在屏幕尺寸上,它們提供的輸入方式也可能不同。因此,想要開發出跨設備通用的網頁,還要做一點別的事。
把事件統一起來處理用戶的輸入要用到事件。鼠標的話,有我們熟悉的mouseover、click等,觸摸的話,也有touchstart、touchend等。不過,這樣看就是要分別對兩種輸入做處理了,大概有點麻煩?如果邏輯也很近似的話,是不是還覺得有點不劃算?
如果能有一類事件,可以同時處理鼠標、觸摸屏這些“雖不同但感覺有那么一點相似”的輸入就好了。對的,可以有,這就是本文要介紹的Pointer Events了。它已經被W3C加入到推薦規范中。
抽象輸入:Pointer前面說鼠標、觸摸屏它們“雖不同但感覺有那么一點相似”,這其實是有章可循的。無論是鼠標還是觸摸屏,其輸入都可以用屏幕上的一個或多個坐標點來概括。Pointer就是描述這種坐標點集合的抽象概念,代表此類輸入。除鼠標和觸摸屏之外,還有一種常見的坐標類型的輸入,是觸控筆,比如數位板或Surface搭配的筆。顯然,觸控筆也是坐標類型,同樣可以用Pointer來表示。
就這樣,Pointer提取了鼠標(mouse)、觸摸屏(touch)、觸控筆(pen)的共通之處,以方便開發跨設備的Web應用。Pointer雖然是一個抽象,但它包含了鼠標、觸摸屏、觸控筆的全部內容。比如,Pointer支持多點觸摸,而且還有壓力、傾斜度等信息。此外,Pointer還提供具體的輸入類型描述,也就是告訴你某個Pointer代表的到底是鼠標、觸摸屏還是觸控筆,以幫助實現針對特定輸入的處理。
引入Pointer還有一個作用,就是如果同時有不同類型的輸入,可以更好地去實現符合JavaScript單線程風格的響應。因為輸入事件被統一了,會比較有條理,不容易出錯。
Pointer相關的一點術語了解Pointer之后,還需要注意一些描述Pointer的相關概念,它們算作術語。這里介紹兩個最主要的。
active pointer從名字上看,就是指處于激活狀態(active)的Pointer。實際上,這個詞是指“可以產生事件”的任意Pointer,這是什么意思呢?下面這些例子會比較容易理解:
和設備連接著的鼠標一直是active。
手指與觸摸屏的屏幕接觸著,認定為active。
位于數位板的響應距離以內的觸控筆,認定為active(如果你用過數位板,你一定知道觸控筆只需要懸空在數位板上方一定距離內就可以控制屏幕上的指針,并不需要觸碰到數位板)。
active buttons state這個可以看做在前面的基礎上,更進一步狀態的Pointer。也同樣舉對應的例子:
鼠標有至少一個按鍵按下去了。
手指接觸到觸摸屏。
觸控筆觸碰到數位板(有物理接觸)。
你可能會發現,手指觸摸的例子好像和前面是一樣的。這是因為,就觸摸屏的設備而言,一般是沒有Hover(懸停)狀態一說的。也就是說,對于手指觸摸輸入,一般的認定是,并不能做到在“不產生按下效果”的情況下移動Pointer。
Pointer事件列表和事件對象Pointer雖然是新的概念,但如前文所說,它包含了鼠標、觸摸屏、觸控筆的全部內容。就具體的實現形式來說,它更像是現在常用的鼠標事件的擴展。比如,Pointer的pointerdown事件,正好對應鼠標的mousedown事件,它們非常近似。
原來的時候你這樣為DOM元素添加鼠標事件:
elem.addEventListener("mousemove", mousemoveHandler, false);
現在換成Pointer以支持更多類型的輸入,你只需要這樣:
elem.addEventListener("pointermove", pointermoveHandler, false);
就一般的使用而言,需要用到的Pointer事件有pointerover、pointerenter、pointerdown、pointermove、pointerup、pointerout、pointerleave。它們全部都可以對應上我們熟悉的鼠標事件。不過,平時很常用的click并不在此列,但沒有關系,用pointerup來做就可以。
在事件處理函數里,會有一個event對象,包含事件的相關信息。Pointer的event對象實際上繼承了鼠標的event對象,然后新增了一部分只讀屬性。其中比較重要的幾個:
pointerId這是一個數字,用于分別標識當前處于active狀態的各個Pointer。在任何Pointer的事件處理函數內,都可以依靠這個數字標記來確認處理的是否是同一個Pointer。
pointerType字符串,就是前文所說的告訴你這個Pointer是鼠標(mouse)、觸摸屏(touch)還是觸控筆(pen)。如果是除這些之外的無法識別的輸入,這個屬性會是空字符串。
isPrimary邏輯值,表示這個Pointer是否是“主要的”(primary)。請看下文。
Primary Pointer前文提到過,Pointer支持多點。所以,這個概念可以幫助確認哪一個是首要的點。具體來說,鼠標是只能一個的,所以代表鼠標的那個Pointer,一定是primary。而對于觸摸屏或觸控筆,在多點輸入的情況下,只有“最初”的那一個算作primary。這里“最初”指的是,在pointerdown事件發生的時候,沒有其他同類型(觸摸對觸摸,筆對筆)的active狀態的Pointer存在。
因為一種類型就可以有一個Primary Pointer,所以可以有多個Primary Pointer。比如同時有手指觸摸和鼠標指針,它們的Pointer都會被認定為primary。
一般來說,應用同一時間只響應一個輸入點的情況比較多,因此可以利用Pointer事件對象的isPrimary來忽略掉那些額外的輸入點。
相關的css屬性:touch-action在支持手指觸摸的設備中,一次手指觸摸中的動作,是有默認行為(default behavior)的。比如,縮放(zooming)和平移(panning,和滾動屏幕scrolling同義)。這些默認行為,和完整的Pointer事件是不相容的。根據手指的動作,如果被判定為觸摸的默認行為,就不會再按照預想的那樣觸發Pointer的事件。因此,你可能想要在某些范圍內,確保不觸發觸摸的某些默認行為,保證Pointer事件按照預想進行。
css屬性touch-action一般用在塊元素上,它的取值分別有:
auto默認值。允許任何設備支持的默認行為。
none不會觸發任何默認行為。
pan-x只允許“水平方向的平移”這一默認行為。
pan-y只允許“垂直方向的平移”這一默認行為。
manipulation只允許“平移”和“縮放”這兩種默認行為。設備支持的其他默認行為(也就是auto里額外的部分)不會觸發。
在手機這樣的觸摸屏設備里,通過手指平移來滾動瀏覽網頁是很普遍的,所以應謹慎地用這個屬性來取消部分默認行為。
瀏覽器兼容性根據caniuse上的結果,在默認情況下,除了IE11及Windows 10的Edge,其他所有瀏覽器都不支持。
啊?那怎么投入實用?
Pointer Events Polyfill類似很多其他新的技術規范,Pointer Events也有Polyfill,就叫做Pointer Events Polyfill,由jQuery團隊開發,簡稱PEP。
這個Polyfill并不能實現規范的全部內容,而是有些偏差,因此需要注意幾個地方:
一是touch-action需要用html屬性形式使用。例如:
二是只有設置了touch-action屬性的元素內部,才能觸發Pointer Events。也就是需要偵聽Pointer事件的區域,一定要選至少一個元素加上touch-action。
這樣設置好之后,就可以像使用鼠標事件那樣來使用Pointer Events了,比如結合jQuery的使用示例:
$("#canvas").on("pointermove", function(event) { draw(event); });
加上這個Polyfill后,將支持IE10+及其他各類瀏覽器(包括手機上的)。
和css屬性pointer-events的關系并,沒,有,什,么,關,系,請明確地區分它們。
結語像鏈接跳轉、滾動屏幕這樣的簡單響應,電腦和手機上的瀏覽器默認就已經做好了處理,并不需要我們做什么。但要做跨設備通用的、更復雜的Web應用,Pointer Events可以很大程度上簡化對多種輸入方式的處理。
我是因為一次應用開發中不能容忍click事件在觸摸設備上的延遲,這才找到了Pointer Events。應該說,很贊同Pointer Events的這種化繁為簡的整合理念,但從它目前的瀏覽器兼容性來看,它還有很遠的路要走。不過,隨著未來更多輸入設備的發展,它有可能會以另外的形式再次入場。
(重新編輯自我的博客,原文地址:http://acgtofe.com/posts/2015/11/pointer-events-for-cross-platform)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/111222.html
摘要:把事件統一起來處理用戶的輸入要用到事件。就這樣,提取了鼠標觸摸屏觸控筆的共通之處,以方便開發跨設備的應用。雖然是一個抽象,但它包含了鼠標觸摸屏觸控筆的全部內容。手指與觸摸屏的屏幕接觸著,認定為。 跨設備的問題 平時我們在電腦上訪問的網頁,大部分情況下是用鼠標來控制的。比如說鏈接跳轉,就是鼠標指針移動到鏈接文字或圖片的位置,然后點擊一下。又比如說滾動屏幕,滑動一下鼠標滾輪就可以。 如果是...
推薦 1. JavaScript 在嵌入式設備與物聯網中的應用現狀 https://auth0.com/blog/javasc... 隨著近年來 Web 的發展與 JavaScript 的崛起,JavaScript 被應用到了許多原本不曾想象到的場景中,從服務端、工作站、數據庫、桌面環境到物聯網設備中,都可以見到 JavaScript 的身影。而本文則概括了 JavaScript 在不同的嵌入式微...
推薦 1. JavaScript 在嵌入式設備與物聯網中的應用現狀 https://auth0.com/blog/javasc... 隨著近年來 Web 的發展與 JavaScript 的崛起,JavaScript 被應用到了許多原本不曾想象到的場景中,從服務端、工作站、數據庫、桌面環境到物聯網設備中,都可以見到 JavaScript 的身影。而本文則概括了 JavaScript 在不同的嵌入式微...
推薦 1. JavaScript 在嵌入式設備與物聯網中的應用現狀 https://auth0.com/blog/javasc... 隨著近年來 Web 的發展與 JavaScript 的崛起,JavaScript 被應用到了許多原本不曾想象到的場景中,從服務端、工作站、數據庫、桌面環境到物聯網設備中,都可以見到 JavaScript 的身影。而本文則概括了 JavaScript 在不同的嵌入式微...
閱讀 600·2021-10-08 10:20
閱讀 1490·2021-09-23 11:22
閱讀 3214·2019-08-30 15:55
閱讀 1582·2019-08-28 18:25
閱讀 1857·2019-08-28 18:14
閱讀 1230·2019-08-26 11:37
閱讀 2893·2019-08-26 10:18
閱讀 2420·2019-08-23 18:39