意外と簡単!JavaScriptでタッチイベントを取得しよう

スマートフォンやタブレットでは、マウスでなくタッチパネルで操作を行います。ユーザーが行ったタッチ操作は、JavaScriptでタッチイベントとして取得することができます。タッチイベントは一見難しそうに思えるかも知れませんが、基本的にはマウスイベントと似ているので、それほど違和感なく取り組むことができます。

タッチイベントの種類

タッチイベントは、スマートフォンやタブレットのタッチパネルでタッチ操作をした際に発生します。JavaScriptで取得できる主なタッチイベントの種類とイベントの発生するタイミングは下記の通りです。

touchstart
タッチパネルに指をタッチした時に発生します。
touchmove
タッチパネルに触れたまま、指を動かした時に発生します。
touchend
タッチパネルに触れていた指を離した時に発生します。
touchcancel
タッチパネルに触れている最中にシステム側から強制的にキャンセルされた際に発生します。スマートフォンでの着信時の他、iPadでマルチタスク用ジェスチャをオンにしている場合は、4, 5本の指で操作した際に発生することがあります。

タッチイベントのイベントリスナー

タッチイベントのイベントリスナーも他のイベントと同じようにaddEventListener()で追加することができます。下記の例では、実行環境がタッチイベントをサポートしているかを調べ、サポートしている場合のみ、タッチイベントのリスナーを追加するようにしています。

JavaScript

if ("ontouchstart" in window) {
  _div.addEventListener("touchstart", touchHandler, false);
  _div.addEventListener("touchmove", touchHandler, false);
  document.addEventListener("touchend", touchHandler, false);
  document.addEventListener("touchcancel", touchHandler, false);
}

タッチイベントのイベントオブジェクト

タッチイベントのイベントオブジェクトは、主に下記のようなプロパティを持っています。マウスイベントと違い、タッチイベントの場合は複数の指が同時にタッチするケースがあるため、各指の情報は配列に格納されています。

type
発生したイベントの種類を表す文字列
touches
タッチパネルに触れている指の情報を持った配列
targetTouches
ターゲットオブジェクト内でタッチし始めた指の情報を持った配列
changedTouches
タッチイベントが発生する原因となった指の情報を持った配列

タッチ操作の情報を取得する

イベントオブジェクトのtouches, targetTouches, changedTouchesから、タッチ操作の情報を取得することができます。identifierは識別子、targetはイベントが発生したノードとなります。また、screenX, screenY, pageX, pageY, clientX, clientYといったプロパティからタッチしている座標を取得することができます。

下記のサンプルでは、div内をタッチすると各指の情報をHTMLで出力するようにしています。まず、preventDefault()でスクロールや拡大/縮小といったブラウザのデフォルトの動作を止め、typeプロパティの値によって処理を分岐しています。

touchstart, touchmoveでは、touchesプロパティからタッチしている指の情報を取得し、touchcancel, touchendでは、changedTouchesプロパティから離した指の情報を取得しています。

JavaScript

function touchHandler(e) {
  e.preventDefault();
  switch (e.type) {
    case "touchstart" :
      if (_cancelReport) {
        _div.removeChild(_cancelReport);
        _cancelReport = null;
      }
    case "touchmove" :
      var touches = e.touches;
      var l = touches.length;
      for (var i = 0; i < l; ++i) {
        var touch = touches[i];
        var p = getParagraph(touch.identifier);
        var html = createHTML(e.type, touch);
        p.innerHTML = html;
      }
      break;
    case "touchcancel" :
      if (!_cancelReport) {
        _cancelReport = document.createElement("p");
        _cancelReport.setAttribute("id", "cancel");
        _cancelReport.innerHTML = "touchcancel";
        _div.appendChild(_cancelReport);
      }
    case "touchend" :
      var touches = e.changedTouches;
      var l = touches.length;
      for (var i = 0; i < l; ++i) {
        var touch = touches[i];
        removeParagraph(touch.identifier);
      }
      break;
  }
}

function createHTML(type, touch) {
  var html = "type:" + type + BR;
  html += "identifier:" + touch.identifier + BR;
  html += "target:" + touch.target + BR;
  html += "screenX:" + touch.screenX + BR;
  html += "screenY:" + touch.screenY + BR;
  html += "pageX:" + touch.pageX + BR;
  html += "pageY:" + touch.pageY + BR;
  html += "clientX:" + touch.clientX + BR;
  html += "clientY:" + touch.clientY + BR;
  html += HR;
  return html;
}