向前邁進

Sérgio Gomes

過去只要用手指著網路事物,有一個滑鼠, 有時你是按下按鈕的,才是這樣有些事情無法 而是將滑鼠模擬成 1 個滑鼠,而開發人員也知道要考量哪些因素。

不過,簡單來說不見得是好事。隨著時間過去, 重要的是,並非所有事情都 (或假裝) 是滑鼠 壓力感感和傾斜度感知筆,可帶來驚人的創作自由;您可以 使用手指,只須用到裝置和手。哈囉 手指在耳機上時不能使用超過一根手指?

包括觸控事件 等候一段時間,但這是完全獨立的 API 特別是觸控功能,如果您的程式碼偵測到兩個獨立的事件模型,則必須使用 都想要同時支援滑鼠和觸控功能Chrome 55 搭載較新的標準 來整合兩個模型:指標事件。

單一事件模型

指標事件可統整 瀏覽器的指標輸入模型,可將觸控、原子和滑鼠結合在一起 合併為一組事件例如:

document.addEventListener('pointermove',
    ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
    ev => console.log('The pointer is now over foo.'));

下列是所有可進行的活動清單,應該很陌生 您熟悉滑鼠事件

pointerover 指標已進入元素的定界框。 如果裝置支援懸停功能, pointerdown 事件。
pointerenter pointerover 類似,但不含對話框和帳號代碼 不同的子系 規格詳情
pointerdown 指標已進入使用中按鈕狀態,按鈕 系統建立聯繫或聯繫方式 (取決於 輸入裝置
pointermove 指標位置已變更。
pointerup 指標已離開使用中的按鈕狀態。
pointercancel 發生各種問題,意味著指標不太可能發出任何提醒 還有更多事件。因此,請先取消所有進行中的動作,再前往 返回中立輸入狀態
pointerout 指標離開元素或畫面的定界框。同時, pointerup (如果裝置不支援懸停功能)。
pointerleave pointerout 類似,但不含對話框和帳號代碼 不同的子系 規格詳情
gotpointercapture 元素已收到指標擷取
lostpointercapture 正在擷取的指標 已發布。

不同輸入類型

一般來說,指標事件可讓您以無輸入方式編寫程式碼 因此您不必為不同的輸入裝置註冊個別的事件處理常式。 當然,您仍然必須留意不同輸入類型之間的差異,例如 懸停概念如何區分不同的輸入裝置類型 不同輸入內容的程式碼/功能 在同一個事件處理常式內,使用 pointerType 屬性 PointerEvent 存取 API舉例來說,如要編寫側邊導覽匣的程式碼 pointermove 事件包含以下邏輯:

switch(ev.pointerType) {
    case 'mouse':
    // Do nothing.
    break;
    case 'touch':
    // Allow drag gesture.
    break;
    case 'pen':
    // Also allow drag gesture.
    break;
    default:
    // Getting an empty string means the browser doesn't know
    // what device type it is. Let's assume mouse and do nothing.
    break;
}

預設動作

在支援觸控功能的瀏覽器中,特定手勢可用於捲動、縮放或重新整理網頁。 如果採用觸控事件,您仍會收到事件,但這些是這些預設動作 舉例來說,當使用者捲動畫面時,仍會觸發 touchmove

透過指標事件,每當觸發捲動或縮放等預設動作時, 您會收到 pointercancel 事件,指出瀏覽器已執行 指標的控制。例如:

document.addEventListener('pointercancel',
    ev => console.log('Go home, the browser is in charge now.'));

內建速度:預設模型可改善效能。 與觸控事件相比 您需要在何處執行 被動事件監聽器 達到一樣的回應速度

如果您想阻止瀏覽器取得 touch-action敬上 CSS 屬性。如果將元素設為 none,系統就會停用所有 回應了瀏覽器定義的動作。不過您需要執行 其他值以進行更精細的控制,例如 pan-x, 瀏覽器會回應 X 軸上的移動,而非 Y 軸。Google 瀏覽器 55 支援下列值:

auto 預設;瀏覽器可執行任何預設動作
none 瀏覽器不得執行任何預設動作。
pan-x 瀏覽器只能執行水平捲動的預設動作。
pan-y 瀏覽器只能執行垂直捲動的預設動作。
pan-left 瀏覽器只能執行水平捲動預設動作。 即可將頁面向左平移
pan-right 瀏覽器只能執行水平捲動預設動作。 只想將頁面向右平移
pan-up 瀏覽器只能執行垂直捲動的預設動作。 只會將頁面向上平移
pan-down 瀏覽器只能執行垂直捲動的預設動作。 只會將頁面向下平移
manipulation 瀏覽器只能執行捲動和縮放動作。

指標擷取

過去曾花費在挫折的小時偵錯故障的 mouseup 事件,直到使用者點選按鈕後判斷該停用事件。 是否超出點擊目標?沒有?好吧,也許只是我自己才對。

然而,直到目前為止,這個問題有了更好的解決辦法。沒問題, 您可以在文件中設定 mouseup 處理常式,並在 持續追蹤各種資訊這不是最乾淨的解決方案 如果您正在建構網頁元件,想讓使用者 而且系統互不相關

以指標事件來說,您可以運用更好的解決方案 擷取指標、 ,以便隨時取得該 pointerup 事件 (或任何其他 好友)。

const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
    console.log('Button down, capturing!');
    // Every pointer has an ID, which you can read from the event.
    foo.setPointerCapture(ev.pointerId);
});

foo.addEventListener('pointerup', 
    ev => console.log('Button up. Every time!'));

瀏覽器支援

撰寫本文時,Internet Explorer 11 支援指標事件。 Microsoft Edge、Chrome 和 Opera,且 Firefox 的部分支援。你可以 請前往 caniuse.com 查看最新的清單

您可以將指標事件 polyfill 用於 填補缺口此外,如要在執行階段檢查瀏覽器支援, 直截了當:

if (window.PointerEvent) {
    // Yay, we can use pointer events!
} else {
    // Back to mouse and touch events, I guess.
}

指標事件很適合使用漸進式增強功能: 修改初始化方法,進行上述檢查、新增指標事件 if 區塊中的處理常式,並將滑鼠/觸控事件處理常式移至 else 區塊。

趕快試用看看,並分享你的想法!