使用觸控事件

如今,大多數 Web 內容都是為鍵盤和滑鼠輸入設計的。然而,帶觸控式螢幕的裝置(尤其是行動式裝置)已成為主流,Web 應用程式可以透過使用 觸控事件 直接處理基於觸控的輸入,或者應用程式可以使用解釋後的滑鼠事件作為應用程式輸入。使用滑鼠事件的一個缺點是它們不支援併發使用者輸入,而觸控事件支援多個同時輸入(可能位於觸控表面的不同位置),從而增強了使用者體驗。

觸控事件介面支援應用程式特定的單點和多點觸控互動,例如雙指手勢。多點觸控互動在手指(或觸控筆)首次接觸接觸面時開始。隨後可能有其他手指接觸表面,並可選擇性地在觸控表面上移動。當手指從表面移開時,互動結束。在此互動過程中,應用程式會在開始、移動和結束階段接收觸控事件。應用程式可以為其觸控輸入應用自己的語義。

介面

觸控事件由三個介面(TouchTouchEventTouchList)以及以下事件型別組成:

  • touchstart - 當觸控點放置在觸控表面上時觸發。
  • touchmove - 當觸控點沿觸控表面移動時觸發。
  • touchend - 當觸控點從觸控表面移除時觸發。
  • touchcancel - 當觸控點以實現特定方式中斷時觸發(例如,建立了過多的觸控點)。

Touch 介面代表觸控感應裝置上的單個接觸點。接觸點通常被稱為觸控點或簡稱為觸控。觸控通常由手指或觸控筆在觸控式螢幕、筆或觸控板上產生。觸控點的屬性包括一個唯一的識別符號、觸控點的目標元素以及觸控點相對於視口、頁面和螢幕位置的XY座標。

TouchList 介面代表一個觸控表面的接觸點列表,每個接觸點對應一個觸控點。因此,如果使用者用一根手指激活了觸控表面,列表將包含一項;如果使用者用三根手指觸摸了表面,列表長度將為三。

TouchEvent 介面表示在觸控感應表面的接觸狀態發生變化時傳送的事件。狀態變化包括開始接觸觸控表面、在保持接觸表面的同時移動觸控點、釋放觸控點以及取消觸控事件。此介面的屬性包括幾個修飾鍵(例如 shift 鍵)的狀態以及以下觸控列表:

  • touches - 當前螢幕上所有觸控點的列表。
  • targetTouches - 目標 DOM 元素上觸控點的列表。
  • changedTouches - 其專案取決於關聯事件型別的觸控點的列表。
    • 對於 touchstart 事件,它是當前事件啟用的觸控點的列表。
    • 對於 touchmove 事件,它是自上次事件以來發生變化的觸控點的列表。
    • 對於 touchend 事件,它是從表面移除的觸控點的列表(即,對應於不再觸控表面的手指的觸控點集)。

這些介面共同定義了一套相對底層的特性,但它們支援多種基於觸控的互動,包括熟悉的諸如多指滑動、旋轉、捏合和縮放的多點觸控手勢。

從介面到手勢

應用程式在定義手勢語義時可能會考慮不同的因素。例如,觸控點從起始位置到結束位置的移動距離。另一個潛在的因素是時間;例如,觸控開始和觸控結束之間經過的時間,或者旨在建立雙擊手勢的兩次連續點選之間的時間間隔。滑動的方向(例如從左到右,從右到左等)是另一個需要考慮的因素。

應用程式使用的觸控列表取決於應用程式手勢的語義。例如,如果應用程式支援在單個元素上進行單點觸控(點選),它將在 touchstart 事件處理程式中使用 targetTouches 列表來以應用程式特定的方式處理觸控點。如果應用程式支援任意兩個觸控點的雙指滑動,它將在 touchmove 事件處理程式中使用 changedTouches 列表來確定是否有兩個觸控點已移動,然後以應用程式特定的方式實現該手勢的語義。

當只有一個活動的觸控點時,瀏覽器通常會分派模擬的滑鼠和點選事件。涉及兩個或更多活動觸控點的多點觸控互動通常只會生成觸控事件。要防止傳送模擬的滑鼠事件,請在觸控事件處理程式中使用 preventDefault() 方法。如果您想同時與滑鼠和觸控進行互動,請改用 指標事件

基本步驟

本節包含使用上述介面的基本用法。有關更詳細的示例,請參閱 觸控事件概述

為每種觸控事件型別註冊事件處理程式。

js
// Register touch event handlers
someElement.addEventListener("touchstart", process_touchstart);
someElement.addEventListener("touchmove", process_touchmove);
someElement.addEventListener("touchcancel", process_touchcancel);
someElement.addEventListener("touchend", process_touchend);

在事件處理程式中處理事件,實現應用程式的手勢語義。

js
// touchstart handler
function process_touchstart(ev) {
  // Use the event's data to call out to the appropriate gesture handlers
  switch (ev.touches.length) {
    case 1:
      handle_one_touch(ev);
      break;
    case 2:
      handle_two_touches(ev);
      break;
    case 3:
      handle_three_touches(ev);
      break;
    default:
      gesture_not_supported(ev);
      break;
  }
}

訪問觸控點的屬性。

js
// Create touchstart handler
someElement.addEventListener("touchstart", (ev) => {
  // Iterate through the touch points that were activated
  // for this element and process each event 'target'
  for (const touch of ev.targetTouches) {
    process_target(touch.target);
  }
});

阻止瀏覽器處理模擬的滑鼠事件

js
// touchmove handler
function process_touchmove(ev) {
  // Set call preventDefault()
  ev.preventDefault();
}

最佳實踐

以下是使用觸控事件時需要考慮的一些最佳實踐

  • 儘量減少在觸控處理程式中完成的工作量。
  • 將觸控點處理程式新增到特定的目標元素(而不是整個文件或文件樹中更高的節點)。
  • touchstart 中新增 touchmovetouchendtouchcancel 事件處理程式。
  • 目標觸控元素或節點應足夠大,以便容納手指觸控。如果目標區域太小,觸控它可能會導致相鄰元素觸發其他事件。

實現和部署狀態

觸控事件瀏覽器相容性資料表明,移動瀏覽器對觸控事件的支援相對廣泛,而桌面瀏覽器的支援則滯後,儘管正在進行其他實現。

關於觸控點的 觸控區域(使用者與觸控表面之間的接觸區域)的一些新功能正在標準化過程中。新功能包括最能概括觸控點與觸控表面接觸區域的橢圓的XY半徑。觸控點的旋轉角度(描述橢圓以使其與接觸區域對齊所需的旋轉度數)以及施加到觸控點的壓力量也正在標準化。

指標事件呢?

新輸入機制的引入增加了處理各種輸入事件(如按鍵事件、滑鼠事件、筆/觸控筆事件和觸控事件)的應用程式的複雜性。為了幫助解決這個問題,指標事件 API 定義了用於處理來自滑鼠、筆、觸控式螢幕等裝置的硬體無關指標輸入的事件和相關介面。也就是說,抽象的指標建立了一個統一的輸入模型,可以表示手指、筆/觸控筆或滑鼠的接觸點。

指標事件模型可以簡化應用程式的輸入處理,因為指標代表來自任何輸入裝置的輸入。此外,指標事件型別與滑鼠事件型別(例如 pointerdownpointerup)非常相似,因此處理指標事件的程式碼與滑鼠處理程式碼非常接近。

指標事件在瀏覽器中的實現狀態相對較高,Chrome、Firefox、IE11 和 Edge 具有完整的實現。

另見