jQuery Sortableがスマホなどのタッチスクリーンで使えない場合の対処法

このコードをjQueryライブラリおよびjQuery UI関連のコードの後に追加して、タッチスクリーンに関するいくつかのプロパティを修正してください。
jQuery UIにTouch対応を追加(タッチ→マウス変換)
(function($){
if (!('ontouchstart' in window)) return;
var proto = $.ui.mouse.prototype;
var _mouseInit = proto._mouseInit;
$.extend(proto, {
_mouseInit: function(){
this.element.on("touchstart." + this.widgetName, $.proxy(this, "_touchStart"));
_mouseInit.apply(this, arguments);
},
_touchStart: function(event){
if (event.originalEvent.touches.length !== 1) return false;
if (!this._mouseCapture(event, false)) return true;
this.element
.on("touchmove." + this.widgetName, $.proxy(this, "_touchMove"))
.on("touchend." + this.widgetName, $.proxy(this, "_touchEnd"));
this._modifyEvent(event);
$(document).trigger("mouseup"); // 重置 mouseHandled
this._mouseDown(event);
return false;
},
_touchMove: function(event){
this._modifyEvent(event);
this._mouseMove(event);
},
_touchEnd: function(event){
this.element
.off("touchmove." + this.widgetName)
.off("touchend." + this.widgetName);
this._mouseUp(event);
},
_modifyEvent: function(event){
var touch = event.originalEvent.touches[0] || event.originalEvent.changedTouches[0];
event.which = 1;
event.pageX = touch.pageX;
event.pageY = touch.pageY;
}
});
})(jQuery);
コード解説
$.support.touch
の強制設定を廃止し、標準的なタッチ対応検出(ontouchstart
)を使用。.bind()
/.unbind()
を.on()
/.off()
に置き換え、jQuery の現行仕様に準拠。clientX
ではなくpageX
を使用して、スクロールがあるページでも正確な位置を取得可能に。- イベント処理をモジュール化し、Sortable に特化したタッチ処理ロジックを保守性の高い形に改善。
- Pointer Events の活用も可能な設計に近づけることで、将来的な拡張にも対応しやすく。
注意点・補足
- モバイル端末でのクリックイベントとの競合を避けるため、タップ操作には
click
よりtouchstart
を使うことを推奨。 - jQuery UI のバージョンによっては、内部構造が異なる場合があるため、導入時はテストを行うこと。
まとめ
この最適化されたコードは、jQuery UI の Sortable ウィジェットをスマートフォンやタブレットなどのタッチデバイスで正しく動作させるための、現代的で安全性の高い実装です。
従来の .bind()
や非推奨のプロパティ操作を排除し、タッチイベントをより正確にマウスイベントに変換することで、スクロールやクリックとの競合といった問題を最小限に抑えながら、快適なドラッグ&ドロップ操作を実現しています。
また、このアプローチは jQuery UI に依存しながらも、将来的に Pointer Events やモダンなドラッグライブラリへの移行がしやすい構造になっており、保守性・拡張性の両面でも優れたベースとなります。