JavaScript 觸摸事件

2023-03-20 15:46 更新

觸摸操作概述

瀏覽器的觸摸 API 由三個部分組成。

  • Touch:一個觸摸點
  • TouchList:多個觸摸點的集合
  • TouchEvent:觸摸引發(fā)的事件實例

Touch接口的實例對象用來表示觸摸點(一根手指或者一根觸摸筆),包括位置、大小、形狀、壓力、目標元素等屬性。有時,觸摸動作由多個觸摸點(多根手指)組成,多個觸摸點的集合由TouchList接口的實例對象表示。TouchEvent接口的實例對象代表由觸摸引發(fā)的事件,只有觸摸屏才會引發(fā)這一類事件。

很多時候,觸摸事件和鼠標事件同時觸發(fā),即使這個時候并沒有用到鼠標。這是為了讓那些只定義鼠標事件、沒有定義觸摸事件的代碼,在觸摸屏的情況下仍然能用。如果想避免這種情況,可以用event.preventDefault方法阻止發(fā)出鼠標事件。

Touch 接口

Touch 接口概述

Touch 接口代表單個觸摸點。觸摸點可能是一根手指,也可能是一根觸摸筆。

瀏覽器原生提供Touch構造函數(shù),用來生成Touch實例。

var touch = new Touch(touchOptions);

Touch構造函數(shù)接受一個配置對象作為參數(shù),它有以下屬性。

  • identifier:必需,類型為整數(shù),表示觸摸點的唯一 ID。
  • target:必需,類型為元素節(jié)點,表示觸摸點開始時所在的網(wǎng)頁元素。
  • clientX:可選,類型為數(shù)值,表示觸摸點相對于瀏覽器窗口左上角的水平距離,默認為0。
  • clientY:可選,類型為數(shù)值,表示觸摸點相對于瀏覽器窗口左上角的垂直距離,默認為0。
  • screenX:可選,類型為數(shù)值,表示觸摸點相對于屏幕左上角的水平距離,默認為0。
  • screenY:可選,類型為數(shù)值,表示觸摸點相對于屏幕左上角的垂直距離,默認為0。
  • pageX:可選,類型為數(shù)值,表示觸摸點相對于網(wǎng)頁左上角的水平位置(即包括頁面的滾動距離),默認為0。
  • pageY:可選,類型為數(shù)值,表示觸摸點相對于網(wǎng)頁左上角的垂直位置(即包括頁面的滾動距離),默認為0。
  • radiusX:可選,類型為數(shù)值,表示觸摸點周圍受到影響的橢圓范圍的 X 軸半徑,默認為0。
  • radiusY:可選:類型為數(shù)值,表示觸摸點周圍受到影響的橢圓范圍的 Y 軸半徑,默認為0。
  • rotationAngle:可選,類型為數(shù)值,表示觸摸區(qū)域的橢圓的旋轉角度,單位為度數(shù),在0到90度之間,默認值為0。
  • force:可選,類型為數(shù)值,范圍在01之間,表示觸摸壓力。0代表沒有壓力,1代表硬件所能識別的最大壓力,默認為0。

Touch 接口的實例屬性

(1)Touch.identifier

Touch.identifier屬性返回一個整數(shù),表示觸摸點的唯一 ID。這個值在整個觸摸過程保持不變,直到觸摸事件結束。

someElement.addEventListener('touchmove', function (e) {
  for (var i = 0; i < e.changedTouches.length; i++) {
    console.log(e.changedTouches[i].identifier);
  }
}, false);

(2)Touch.screenX,Touch.screenY,Touch.clientX,Touch.clientY,pageX,pageY

Touch.screenX屬性和Touch.screenY屬性,分別表示觸摸點相對于屏幕左上角的橫坐標和縱坐標,與頁面是否滾動無關。

Touch.clientX屬性和Touch.clientY屬性,分別表示觸摸點相對于瀏覽器視口左上角的橫坐標和縱坐標,與頁面是否滾動無關。

Touch.pageX屬性和Touch.pageY屬性,分別表示觸摸點相對于當前頁面左上角的橫坐標和縱坐標,包含了頁面滾動帶來的位移。

(3)Touch.radiusX,Touch.radiusY,Touch.rotationAngle

Touch.radiusX屬性和Touch.radiusY屬性,分別返回觸摸點周圍受到影響的橢圓范圍的 X 軸半徑和 Y 軸半徑,單位為像素。乘以 2 就可以得到觸摸范圍的寬度和高度。

Touch.rotationAngle屬性表示觸摸區(qū)域的橢圓的旋轉角度,單位為度數(shù),在090度之間。

上面這三個屬性共同定義了用戶與屏幕接觸的區(qū)域,對于描述手指這一類非精確的觸摸,很有幫助。指尖接觸屏幕,觸摸范圍會形成一個橢圓,這三個屬性就用來描述這個橢圓區(qū)域。

下面是一個示例。

div.addEventListener('touchstart', rotate);
div.addEventListener('touchmove', rotate);
div.addEventListener('touchend', rotate);

function rotate(e) {
  var touch = e.changedTouches.item(0);
  e.preventDefault();

  src.style.width = touch.radiusX * 2 + 'px';
  src.style.height = touch.radiusY * 2 + 'px';
  src.style.transform = 'rotate(' + touch.rotationAngle + 'deg)';
};

(4)Touch.force

Touch.force屬性返回一個01之間的數(shù)值,表示觸摸壓力。0代表沒有壓力,1代表硬件所能識別的最大壓力。

(5)Touch.target

Touch.target屬性返回一個元素節(jié)點,代表觸摸發(fā)生時所在的那個元素節(jié)點。即使觸摸點已經(jīng)離開了這個節(jié)點,該屬性依然不變。

TouchList 接口

TouchList接口表示一組觸摸點的集合。它的實例是一個類似數(shù)組的對象,成員是Touch的實例對象,表示所有觸摸點。用戶用三根手指觸摸,產(chǎn)生的TouchList實例就會包含三個成員,每根手指的觸摸點對應一個Touch實例對象。

它的實例主要通過觸摸事件的TouchEvent.touches、TouchEvent.changedTouches、TouchEvent.targetTouches這幾個屬性獲取。

它的實例屬性和實例方法只有兩個。

  • TouchList.length:數(shù)值,表示成員數(shù)量(即觸摸點的數(shù)量)。
  • TouchList.item():返回指定位置的成員,它的參數(shù)是該成員的位置編號(從零開始)。

TouchEvent 接口

概述

TouchEvent 接口繼承了 Event 接口,表示由觸摸引發(fā)的事件實例,通常來自觸摸屏或軌跡板。除了被繼承的屬性以外,它還有一些自己的屬性。

瀏覽器原生提供TouchEvent()構造函數(shù),用來生成觸摸事件的實例。

new TouchEvent(type, options)

TouchEvent()構造函數(shù)可以接受兩個參數(shù),第一個參數(shù)是字符串,表示事件類型;第二個參數(shù)是事件的配置對象,該參數(shù)是可選的,對象的所有屬性也是可選的。除了Event接口的配置屬性,該接口還有一些自己的配置屬性。

  • touchesTouchList實例,代表所有的當前處于活躍狀態(tài)的觸摸點,默認值是一個空數(shù)組[]。
  • targetTouchesTouchList實例,代表所有處在觸摸的目標元素節(jié)點內(nèi)部、且仍然處于活動狀態(tài)的觸摸點,默認值是一個空數(shù)組[]
  • changedTouchesTouchList實例,代表本次觸摸事件的相關觸摸點,默認值是一個空數(shù)組[]
  • ctrlKey:布爾值,表示 Ctrl 鍵是否同時按下,默認值為false。
  • shiftKey:布爾值,表示 Shift 鍵是否同時按下,默認值為false。
  • altKey:布爾值,表示 Alt 鍵是否同時按下,默認值為false。
  • metaKey:布爾值,表示 Meta 鍵(或 Windows 鍵)是否同時按下,默認值為false。

實例屬性

TouchEvent 接口的實例具有Event實例的所有屬性和方法,此外還有一些它自己的實例屬性,這些屬性全部都是只讀。

(1)TouchEvent.altKey,TouchEvent.ctrlKey,TouchEvent.shiftKey,TouchEvent.metaKey

  • TouchEvent.altKey:布爾值,表示觸摸時是否按下了 Alt 鍵。
  • TouchEvent.ctrlKey:布爾值,表示觸摸時是否按下了 Ctrl 鍵。
  • TouchEvent.shiftKey:布爾值:表示觸摸時是否按下了 Shift 鍵。
  • TouchEvent.metaKey:布爾值,表示觸摸時是否按下了 Meta 鍵(或 Windows 鍵)。

下面是一個示例。

someElement.addEventListener('touchstart', function (e) {
  console.log('altKey = ' + e.altKey);
  console.log('ctrlKey = ' + e.ctrlKey);
  console.log('metaKey = ' + e.metaKey);
  console.log('shiftKey = ' + e.shiftKey);
}, false);

(2)TouchEvent.changedTouches

TouchEvent.changedTouches屬性返回一個TouchList實例,成員是一組Touch實例對象,表示本次觸摸事件的相關觸摸點。

對于不同的時間,該屬性的含義有所不同。

  • touchstart事件:被激活的觸摸點
  • touchmove事件:發(fā)生變化的觸摸點
  • touchend事件:消失的觸摸點(即不再被觸碰的點)

下面是一個示例。

someElement.addEventListener('touchmove', function (e) {
  for (var i = 0; i < e.changedTouches.length; i++) {
    console.log(e.changedTouches[i].identifier);
  }
}, false);

(3)TouchEvent.touches

TouchEvent.touches屬性返回一個TouchList實例,成員是所有仍然處于活動狀態(tài)(即觸摸中)的觸摸點。一般來說,一個手指就是一個觸摸點。

下面是一個示例。

someElement.addEventListener('touchstart', function (e) {
  switch (e.touches.length) {
    // 一根手指觸摸
    case 1: handle_one_touch(e); break;
    // 兩根手指觸摸
    case 2: handle_two_touches(e); break;
    // 三根手指觸摸
    case 3: handle_three_touches(e); break;
    // 其他情況
    default: console.log('Not supported'); break;
  }
}, false);

(4)TouchEvent.targetTouches

TouchEvent.targetTouches屬性返回一個TouchList實例,成員是觸摸事件的目標元素節(jié)點內(nèi)部、所有仍然處于活動狀態(tài)(即觸摸中)的觸摸點。

function touches_in_target(ev) {
  return (ev.touches.length === ev.targetTouches.length ? true : false);
}

上面代碼用來判斷,是否所有觸摸點都在目標元素內(nèi)。

觸摸事件的種類

觸摸引發(fā)的事件,有以下幾種??梢酝ㄟ^TouchEvent.type屬性,查看到底發(fā)生的是哪一種事件。

  • touchstart:用戶開始觸摸時觸發(fā),它的target屬性返回發(fā)生觸摸的元素節(jié)點。
  • touchend:用戶不再接觸觸摸屏時(或者移出屏幕邊緣時)觸發(fā),它的target屬性與touchstart事件一致的,就是開始觸摸時所在的元素節(jié)點。它的changedTouches屬性返回一個TouchList實例,包含所有不再觸摸的觸摸點(即Touch實例對象)。
  • touchmove:用戶移動觸摸點時觸發(fā),它的target屬性與touchstart事件一致。如果觸摸的半徑、角度、力度發(fā)生變化,也會觸發(fā)該事件。
  • touchcancel:觸摸點取消時觸發(fā),比如在觸摸區(qū)域跳出一個模態(tài)窗口(modal window)、觸摸點離開了文檔區(qū)域(進入瀏覽器菜單欄)、用戶的觸摸點太多,超過了支持的上限(自動取消早先的觸摸點)。

下面是一個例子。

var el = document.getElementsByTagName('canvas')[0];
el.addEventListener('touchstart', handleStart, false);
el.addEventListener('touchmove', handleMove, false);

function handleStart(evt) {
  evt.preventDefault();
  var touches = evt.changedTouches;
  for (var i = 0; i < touches.length; i++) {
    console.log(touches[i].pageX, touches[i].pageY);
  }
}

function handleMove(evt) {
  evt.preventDefault();
  var touches = evt.changedTouches;
  for (var i = 0; i < touches.length; i++) {
    var touch = touches[i];
    console.log(touch.pageX, touch.pageY);
  }
}


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號