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