読者です 読者をやめる 読者になる 読者になる

jQueryUIのsortableをiPhone/iPadで使うときにマルチタッチを無効化する方法

JavaScript

jQueryUIのsortableって便利ですよね。でも、iPhoneiPadだとタッチイベントをうまく検出してくれずそのままでは動作しません。
そこでjQuery の sortable を iPad 対応するで紹介されているようにタッチイベントをマウスイベントに置き換えて動作させる方法があります。

function dispatchMouseEvent( event_type, touch_event ){
  var simulatedEvent = document.createEvent("MouseEvent");
  simulatedEvent.initMouseEvent(
  event_type, true, true, window, 1,
  touch_event.screenX, touch_event.screenY,
  touch_event.clientX, touch_event.clientY, false,
  false, false, false, 0, null);
  touch_event.target.dispatchEvent(simulatedEvent);
}

function touchHandler(event){
  var touches = event.changedTouches;
  event.preventDefault();
  var first = touches[0];
  var type = "";
  switch(event.type){
    case "touchstart":
      type = "mousedown";
      break;
    case "touchend":
      type = "mouseup";
      break;
    case "touchmove":
      type = "mousemove";
      break;
    default:
      return;
  }
  dispatchMouseEvent(type, first);
}

var label_elements = $(".sortable");
for(var i=0;i < label_elements.length;i++){
  label_elements[i].addEventListener("touchstart",  touchHandler, false);
  label_elements[i].addEventListener("touchmove",   touchHandler, false);
  label_elements[i].addEventListener("touchend",    touchHandler, false);
  label_elements[i].addEventListener("touchcancel", touchHandler, false);
}

これでとりあえずは動作するのですが、一つ問題があります。二本指で操作するとソート要素がずれたりおかしな動きになるのです。
touchHandlerの中でtouches[0]というように1本目の指を指定して座標を取得しているにも関わらず、event.typeは指にかかわらず取得できてしまうのが原因です。
ここではマルチタッチの操作を無効化してしまいましょう。

function touchHandler(event){
  if (event.touches.length > 1){return;} //この1行を追加
  var touches = event.changedTouches;
  event.preventDefault();
  var first = touches[0];
  var type = "";
  switch(event.type){
    case "touchstart":
      type = "mousedown";
      break;
    case "touchend":
      type = "mouseup";
      break;
    case "touchmove":
      type = "mousemove";
      break;
    default:
      return;
  }
  dispatchMouseEvent(type, first);
}

つまり2本以上の指で操作すると、何もせず処理を抜けさせるわけですね。
タッチイベントは面白いけど、考えることも多いですね。