瀏覽器的統一指標事件:Pointer Event

| | 0 Comments| 10:43
Categories:

在早期的瀏覽器,輸入的事件其實相對單純,只有考慮到滑鼠和鍵盤兩種;而當時的滑鼠事件,其實就是 clickmousedownmouseup 等等的事件(Mouse Event、參考)。但是當手機、平板開始流行時候,再行動裝置上的主要操作介面,已經從滑鼠變成是觸控了~

由於觸控和滑鼠的操作邏輯,算是有根本上的差異的,再加上大部分的裝置又支援多點觸控,所以雖然瀏覽器大多會把觸控的事件對應回傳統的滑鼠事件,但是如果希望能有更細緻的操作,傳統的滑鼠事件是不夠用的。

而目前 W3C 針對觸控操作的部分,則有兩種事件模型可以使用,其中一個是專門為了觸控設計的 Touch Event(W3C),這應該算是目前大部分行動瀏覽器所支援的事件架構;而另一種,則是由微軟所提出的、試圖統一所有指標裝置的事件架構、Pointer Event(W3C)。

相較於目前主流的 Touch Event 只有去處理觸控的事件,微軟提出的 Pointer Event 則是希望能把所有的指標事件都統一來做管理、讓程式開發時能更簡單地使用。右圖就是官方的示意圖。

以目前定義的標準來說,Pointer Event 能支援的指標裝置包括了滑鼠、觸控(手指)、以及筆型裝置;而除了能整合不同類型的指標裝置外,Pointer Event 針對能支援的硬體,也多了相當多額外的參數,像是壓力、寬度、高度,甚至比型裝置的傾斜程度等等。

這些更詳細的資訊,基本上都是可以讓開發者根據各種指標裝置的輸入,來做更細緻的處理的~再加上透過 Pointer Event 的架構,可以一次性地處理掉滑鼠和觸控等裝置的事件,所以在 Heresy 來看,應該算是一種相對好的架構。


跨瀏覽器

很遺憾的,目前基本上只有微軟自家的 Internet Explorer(10 )有原生支援 Pointer event(不過也不大一樣,請參考 MSDN),其他的瀏覽器,都僅支援 Touch Even;而再加上 IE 本身並不支援 Touch Event,所以變成要跨瀏覽器處理觸控事件,就得寫兩個版本了…

不過還好,微軟他們為了推動自己提出的 Pointer Event,所以也有提供一個讓其他瀏覽器也能支援 Pointer Event 的 JavaScript 函式庫、Hand.js!他的官方網站是:

http://handjs.codeplex.com/

基本上只要在網頁裡面引入這個 JavaScript 檔後,Firefox 或 Chrome 也就都可以使用 Pointer Event 了~

詳細的介紹則可以參考《Hand.js: a polyfill for supporting pointer events on every browser》。


事件的定義

Pointer Event 總共定義了八種事件,其列表如下:

  • pointerdown
  • pointerup
  • pointercancel
  • pointermove
  • pointerover
  • pointerout
  • pointerenter
  • pointerleave

基本上,大部分的事件,都可以對應到本來的 mouse event(MSDN 參考),在 W3C 的網頁上,也有針對這些事件的詳細說明;實際上,如果瀏覽器偵測到指鰾是主要的(primary)指標的話,他也會送出滑鼠的事件。

而當觸發事件時,程式可以取得定義為 PointerEvent 的資料,它應該算是繼承了 MouseEvent 的結構後,再附加了一些額外的的資料;其定義如下:

interface PointerEvent : MouseEvent {
readonly    attribute long      pointerId;
readonly    attribute long      width;
readonly    attribute long      height;
readonly    attribute float     pressure;
readonly    attribute long      tiltX;
readonly    attribute long      tiltY;
readonly    attribute DOMString pointerType;
readonly    attribute boolean   isPrimary;
};

其中,每一個指標都有屬於自己的編號、也就是 pointerId;而透過 pointerType 則可以判斷他是哪一種類型的指標,目前的標準包含了 mousepentouch 這三種可能。

而要取得指標的位置的時候,則是可以視需要使用 screenXscreenY,或是 clientXclientY
其他像是 widthheight,就是代表這個指標的大小(應該是給觸控用的),pressure 則是指標裝置的壓力(介於 0-1 之間),而 tileXtileY 則是筆型裝置的傾斜程度。


使用的話,由於 Heresy 自己也是剛開始玩,所以這邊就不自己寫範例了。

在微軟官方的部落格文章《Hand.js: a polyfill for supporting pointer events on every browser》和《Unifying touch and mouse: how Pointer Events will make cross-browsers touch support easy》內,就有展示、以及使用範例了~有興趣寫的話,應該是參考這邊就可以了。另外,它裡面也有提供一個範例網頁(連結),可以做進一步的參考。

而在《Creating an universal virtual touch joystick working for all Touch models thanks to Hand.JS》一文中,也有展示如何使用 Pointer Event 來做一個觸控的搖桿遊戲,應該也算是值得參考的實作。


附註:

  1. Windows 版的 FireFox 預設應該是把觸控事件關閉的,需要手動開啟,否則就算是在平板上用觸控也只會抓到滑鼠事件。
    他的開啟方法是在 FireFox 打開「about:config」的頁面,找到「dom.w3c_touch_events.enabled」這個項目,把他的值從「0」改成「1」。

  2. MouseEvent 的定義(DOM Level 3、參考):

    interface MouseEvent : UIEvent {
    readonly attribute long           screenX;
    readonly attribute long           screenY;
    readonly attribute long           clientX;
    readonly attribute long           clientY;
    readonly attribute boolean        ctrlKey;
    readonly attribute boolean        shiftKey;
    readonly attribute boolean        altKey;
    readonly attribute boolean        metaKey;
    readonly attribute unsigned short button;
    readonly attribute unsigned short buttons;
    readonly attribute EventTarget?   relatedTarget;
    };

參考:

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *