web-dev-qa-db-ja.com

タッチイベントをマウスイベントにマッピングするJavaScript

マウス移動イベントで動作するYUIスライダーを使用しています。 touchmoveイベント(iPhoneおよびAndroid)に応答させたい。 touchmoveイベントが発生したときにマウス移動イベントを生成するにはどうすればよいですか?スクリプトを上部に追加するだけで、touchmoveイベントがマウス移動イベントにマッピングされ、スライダーで何も変更する必要がなくなることを望んでいます。

52
Questioner

これはあなたが望むものだと確信しています:

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

    // initMouseEvent(type, canBubble, cancelable, view, clickCount, 
    //                screenX, screenY, clientX, clientY, ctrlKey, 
    //                altKey, shiftKey, metaKey, button, relatedTarget);

    var simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1, 
                                  first.screenX, first.screenY, 
                                  first.clientX, first.clientY, false, 
                                  false, false, false, 0/*left*/, null);

    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() 
{
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);    
}

タッチイベントをキャプチャし、一致するように独自のマウスイベントを手動で起動しました。コードはそのままでは特に一般的な目的ではありませんが、ほとんどの既存のドラッグアンドドロップライブラリ、およびおそらくほとんどの既存のマウスイベントコードに適応するのは簡単なはずです。このアイデアがiPhone用のWebアプリケーションを開発する人々に役立つことを願っています。

更新:

これを投稿する際、すべてのタッチイベントでpreventDefaultを呼び出すと、リンクが正常に機能しなくなることに気付きました。 preventDefaultを呼び出す主な理由は、電話のスクロールを停止することであり、touchmoveコールバックでのみ呼び出すことでそれを行うことができます。この方法で行う唯一の欠点は、iPhoneがホバーポップアップをドラッグOriginの上に表示する場合があることです。それを防ぐ方法を見つけたら、この投稿を更新します。

2回目の更新:

コールアウトをオフにするCSSプロパティを見つけました:-webkit-touch-callout

104
Mickey Shine

@Mickey Shineの答えに沿って、 Touch Punch は、クリックイベントへのタッチイベントのマッピングを提供します。このサポートをjQuery UIに組み込むために構築されていますが、 コード は参考になります。

5
Pat

ここに戻ってくる将来のユーザーには、次のコードが使用される可能性があります。

var eventMap = {};

(function(){
var eventReplacement = {
    "mousedown": ["touchstart mousedown", "mousedown"],
    "mouseup": ["touchend mouseup", "mouseup"],
    "click": ["touchstart click", "click"],
    "mousemove": ["touchmove mousemove", "mousemove"]
};


for (i in eventReplacement) {
    if (typeof window["on" + eventReplacement[i][0]] == "object") {
        eventMap[i] = eventReplacement[i][0];
    } 
    else {
        eventMap[i] = eventReplacement[i][1];
    };
 };
})();

そして、イベントでは次のように使用します:

$(".yourDiv").on(eventMap.mouseup, function(event) {
      //your code
}
3
Pritam Banerjee

私はついに、Mickeyのソリューションを使用して、彼の初期化関数の代わりにこれを機能させる方法を見つけました。ここでinit関数を使用します。

function init() {
    document.getElementById('filter_div').addEventListener("touchstart", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchmove", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchend", touchHandler, true);
    document.getElementById('filter_div').addEventListener("touchcancel", touchHandler, true);
}

filter_div 'は、チャート範囲フィルターがあるチャート領域であり、タッチ制御を書き換えるのはその領域のみです!

ミッキー、ありがとう。それは素晴らしい解決策でした。

2
Sana

@MickeyのコードをEdgeおよびInternet Explorerで動作させるには、シミュレーションを実行する要素の.cssに次の行を追加します。

.areaWhereSimulationHappens {
    overflow: hidden;
    touch-action: none;
    -ms-touch-action: none;
}

これらの線は、EdgeおよびIEのデフォルトのタッチを防ぎます。ただし、間違った要素に追加すると、スクロールも無効になります(Edgeではデフォルトで発生し、タッチデバイスではIE)。

1
kumardeepakr3