2012年5月22日火曜日

HTML5+JavaScriptによるSwipeの実装例

Manifest+LocalStorageによるオフラインアプリ作成(4)

サンプルアプリで、iOSに似せたSwipeを実装してあります。Swipe画面でテーブルセルをSwipeすると「削除」ボタンが表示がされ、「削除」ボタンタップでテーブルセルが削除されます。
デスクトップではマウス操作で行うことができます。IEではレイアウトが崩れますが、一応Swipe動作します。

このサンプルアプリで使用しているのswipeに関するJavaScriptは次のとおりです。

//Table Cellなどでイベント発生
function swipeCellClicked(event) {
  var div = event.srcElement;
  //Swipeオブジェクトを作る
  new Swipe(div, event);
}
//イベントハンドラの設定などを行う。
Swipe = function(div, event) {
  this.start = new Date().getTime();
  this.div = div;
  //iOSの場合
  if (isIOS) {
    div.addEventListener("touchmove", Swipe.touchMove, false);
    div.addEventListener("touchend", Swipe.touchEnd, false);
  } else {
    //SafariなどaddEventListenerを使うブラウザの場合
    if (typeof div.addEventListener != "undefined") {
      div.addEventListener("mousemove", Swipe.touchMove, false);
      //div.addEventListener("mouseout", Swipe.touchEnd, false);
      div.addEventListener("mouseleave", Swipe.touchEnd, false);
      div.addEventListener("mouseup", Swipe.touchEnd, false);
    } else {
      //IEなどattachEventを使う場合
      div.attachEvent("onmousemove", Swipe.touchMove);
      div.attachEvent("onmouseout", Swipe.touchEnd);
      div.attachEvent("mouseup", Swipe.touchEnd);
    }
  }
  if (typeof event.pageX != "undefined") {
    Swipe.x0 = event.pageX;
    Swipe.y0 = event.pageY;
  } else {
    Swipe.x0 = event.x;
    Swipe.y0 = event.y;
  }
}
//touchMoveまたはmouseMoveイベント。イベント発生位置を保存。
Swipe.touchMove = function(event) {
  if (event != null) {
    if (typeof event.pageX != "undefined") {
      Swipe.x1 = event.pageX;
      Swipe.y1 = event.pageY;
    } else {
      Swipe.x1 = event.x;
      Swipe.y1 = event.y;
    }
  } else {
    Swipe.x0 = Swipe.y0 = Swipe.x1 = Swipe.y1 = 0;
  }
}
//イベント終了時
Swipe.touchEnd = function(event) {
  div = (event == null ? this : event.srcElement);
  //イベントハンドラ削除
  if (isIOS) {
    div.removeEventListener("touchstart", Swipe.touchMove);
    div.removeEventListener("touchmove", Swipe.touchMove);
    div.removeEventListener("touchend", Swipe.touchEnd);
  } else {
    if (typeof div.removeEventListener != "undefined") {
      div.removeEventListener("mousedown", Swipe.touchMove);
      div.removeEventListener("mousemove", Swipe.touchMove);
      div.removeEventListener("mouseout", Swipe.touchEnd);
      div.removeEventListener("mouseleave", Swipe.touchEnd);
      div.removeEventListener("mouseup", Swipe.touchEnd);
    } else {
      div.detachEvent("mousedown", Swipe.touchMove);
      div.detachEvent("onmousemove", Swipe.touchMove);
      div.detachEvent("onmouseout", Swipe.touchEnd);
      div.detachEvent("mouseup", Swipe.touchEnd);
    }
  }
  var dx = Swipe.x1 - Swipe.x0;
  var dy = Swipe.y1 - Swipe.y0;
  //上下移動があまりなく、左右移動が十分ある場合にSwipeとする。
  if ((dx < -50 || dx > 50) && dy > -50 && dy < 50) {
    Swipe.div = div;
    setTimeout(Swipe.appendButton, 10);
  }
  Swipe.x0 = Swipe.y0 = Swipe.x1 = Swipe.y1 = 0;
}

Swipe.div = null;
Swipe.prevSwipedDiv = null;
//Swipeされたときに「削除」ボタンを追加、あるいは既に追加されている場合は削除する。
Swipe.appendButton = function() {
  var div = Swipe.findCellBoxDiv(Swipe.div);
  if (Swipe.prevSwipedDiv != null && Swipe.prevSwipedDiv != div) {
    Swipe.removeButton(Swipe.prevSwipedDiv);
    Swipe.prevSwipedDiv = null;
    return;
  }
  if (Swipe.removeButton(div)) {
    Swipe.prevSwipedDiv = null;
    return;
  }
  Swipe.prevSwipedDiv = div;
  var btn = document.createElement("INPUT");
  btn.type = "button";
  btn.value = "削除";
  btn.className = "swipeDelete";
  if (typeof btn.addEventListener == "undefined") {
    btn.attachEvent("onclick", Swipe.deleteCell);
  } else {
    btn.addEventListener("click", Swipe.deleteCell, false);
  }
  div.appendChild(btn);
}
//既に「削除」ボタンがセットされていたらそれを削除する。
//子要素にINPUT要素があったら削除し、trueを返す。ない場はfalseを返す。
Swipe.removeButton = function(div) {
  if (div.childNodes) {
    for(var i=div.childNodes.length - 1; i>= 0; i--) {
      if (div.childNodes[i].nodeType == 1 && div.childNodes[i].tagName == "INPUT") {
        div.removeChild(div.childNodes[i]);
        return true;
      }
    }
  }
  return false;
}
//「削除」ボタンがタップされたテーブルセルを削除
Swipe.deleteCell = function() {
  var div = Swipe.findCellBoxDiv(event.srcElement);
  div.parentElement.removeChild(div);
  Swipe.prevSwipedDiv = null;
}
//イベントが発生した要素を含むテーブルセル(DIV)を探す。
Swipe.findCellBoxDiv = function(div) {
  var cbDiv = div;
  while(cbDiv != null) {
    if (cbDiv.className == "TableCellBox") {
      return cbDiv;
    }
    cbDiv = cbDiv.parentElement;
  }
  return null;
}

HTML5+JavaScriptによるSwipeの実装例

0 件のコメント: