タッチデバイス用のJavascriptドラッグアンドドロップ[終了]


120

タッチデバイスで動作するドラッグ&ドロッププラグインを探しています。

「ドロップ可能な」要素を許可するjQuery UIプラグインと同様の機能が欲しいのですが。

プラグインjqtouchドラッグサポートしていますが、ノードロップ。

こちらはiPhone / iPadのみに対応したドラッグ&ドロップです。

誰でも私にandroid / iosで動作するドラッグ&ドロッププラグインの方向を教えてもらえますか?

...または、ドロップ機能のためにjqtouchプラグインを更新することが可能かもしれません。AndriodとIOSですでに実行されています。

ありがとう!


1
これは進行中ですが、どのデバイスがそれをサポートするのかわかりません:このplugins.jquery.com/project/mobiledraganddrop ... jQuerymobile.comライブラリを調べましたか?私はまた、この重複SOの質問が見つかりました:stackoverflow.com/questions/3172100/...
iivel

ありがとう。ええmobiledraganddropはモバイルデバイスでのクリックアンドドロップのみをサポートしています。jQuerymobile.comで何も見つかりませんでした。もう1つの質問には、正しいとマークされた回答があり、ソースライセンスが制限されているsencha.com/products/touchを参照しています。
joe

モバイルとデスクトップのブラウザで動作するものに興味があります。
ライム

回答:


258

ドラッグアンドドロップにJquery UIを使用して、マウスイベントをタッチに変換する追加のライブラリを必要に応じて使用できます。推奨されるライブラリはhttps://github.com/furf/jquery-ui-touch-punchですで、これは、JQuery UIからのドラッグアンドドロップがタッチデバイスで機能するはずです

または、私が使用しているこのコードを使用できます。また、マウスイベントをタッチに変換し、魔法のように機能します。

function touchHandler(event) {
    var touch = event.changedTouches[0];

    var simulatedEvent = document.createEvent("MouseEvent");
        simulatedEvent.initMouseEvent({
        touchstart: "mousedown",
        touchmove: "mousemove",
        touchend: "mouseup"
    }[event.type], true, true, window, 1,
        touch.screenX, touch.screenY,
        touch.clientX, touch.clientY, false,
        false, false, false, 0, null);

    touch.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);
}

そしてあなたのdocument.readyでinit()関数を呼び出すだけです

ここからコードが見つかりました


11
おかげで、私のAndroidデバイスでは、データがドラッグ可能になりました。ただし、クリックしたときにクリックイベントが発生しなくなりました。それを修正する方法はありますか?
John Landheer

9
注:イベントリスナーはドキュメント全体に登録されているため、このソリューションでは、Nexus Sでのスクロールも無効になります...
Ethan Leroy '10

29
これを共有してくれてありがとう。ただし、投稿したコードの元の作成者にクレジットを与える必要があります。 ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript
undefined

2
@JohnLandheerドラッグ可能なオブジェクトにのみイベントリスナーをアタッチすることで問題を修正しましたdocument.getElementById('draggableContainer').addEventListener(...
chiliNUT

1
タッチパンチは素晴らしいです。それらの1つは、「うまくいく」ことです。悲しいかな、それはデュアルタッチをサポートしていません...私はそれが見たいです。
DA。

21

これを使用して「クリック」機能を維持したい人は(John Landheerがコメントで述べているように)、いくつかの変更を加えるだけで実行できます。

いくつかのグローバルを追加します。

var clickms = 100;
var lastTouchDown = -1;

次に、switchステートメントを元のステートメントから次のステートメントに変更します。

var d = new Date();
switch(event.type)
{
    case "touchstart": type = "mousedown"; lastTouchDown = d.getTime(); break;
    case "touchmove": type="mousemove"; lastTouchDown = -1; break;        
    case "touchend": if(lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms){lastTouchDown = -1; type="click"; break;} type="mouseup"; break;
    default: return;
}

「クリック」を好みに合わせて調整することもできます。基本的には、「タッチスタート」の直後に「タッチエンド」が続き、クリックをシミュレートするだけです。


@EZ Hart-クリックイベントを有効にするために、上記のコードのどこにコードを配置するか教えていただけませんか?
Valay 2014年

1
@ChakoDesai-回答のコードは、返信を書いてから大幅に編集されています。stackoverflow.com/posts/6362527/revisionsをチェックして、2011年6月30日以降のコードを確認してください。私の答えはそのバージョンに基づいてはるかに理にかなっています。
EZ Hart

@EZ Hart-指定されたURLからコードを更新しました。しかし、なぜ時々click動作し、時々動作しないのですか?
Valay 2014年

@ChakoDesai-あなたのコードを見ていないと確信が持てません。あなたはそのために新しい質問を開きたいかもしれません。
EZ Hart

クリックイベントで上記のコードを動作させるために、更新の答えはここに見つけることができます:stackoverflow.com/questions/28218888/...
Blunderfestを

12

上記のコードをありがとう!-私はいくつかのオプションを試しました、そしてこれはチケットでした。preventDefaultがiPadでのスクロールを妨げているという問題がありました。現在、ドラッグ可能なアイテムをテストしており、これまでのところうまくいきます。

if (event.target.id == 'draggable_item' ) {
    event.preventDefault();
}

これをWindows Phoneでテストしましたか?それともiPhone以外?過去の経験から、これはiPhone / iPadでは完璧に機能するようですが、他のデバイス、特にWindows Phoneではうまく機能しません。
ほぼ初心者の

10

gregpress answerと同じ解決策がありましたが、ドラッグ可能なアイテムはIDではなくクラスを使用していました。動作するようです。

var $target = $(event.target);  
if( $target.hasClass('draggable') ) {  
    event.preventDefault();  
}

4
単に別のセレクターを使用したという事実は、別の回答であることを保証するものではありませんが、代わりに@gregpressの回答にコメントする必要がありました。
bPratik 2012

2
@bPratikが回答をより適切にフォーマットすることを望んでいない限り、そしてコード例全体を提供したという事実は、別の回答を正当化します。彼の答えにリンクするコメントを残すべきだった...
drzaus

8

私が知っている古いスレッド......

@ryuutatsuoの答えの問題は、「クリック」に反応する必要のある入力やその他の要素(入力など)もブロックすることです。そのため、このソリューションを作成しました。このソリューションにより、任意のタッチデバイス(またはコンピュータ)でのmousedown、mousemove、およびmouseupイベントに基づく既存のドラッグアンドドロップライブラリを使用できるようになりました。これはクロスブラウザソリューションでもあります。

私はいくつかのデバイスでテストしましたが、高速に動作します(ThreeDubMediaのドラッグアンドドロップ機能と組み合わせて(http://threedubmedia.com/code/event/dragも参照))。これはjQueryソリューションなので、jQueryライブラリでのみ使用できます。一部の新しい関数はIE9以降では正しく機能しないため、jQuery 1.5.1を使用しました(新しいバージョンのjQueryではテストされていません)。

ドラッグまたはドロップ操作をイベントに追加するに、この関数を最初に呼び出す必要があります

simulateTouchEvents(<object>);

次の構文を使用して、入力用にすべてのコンポーネント/子をブロックしたり、イベント処理を高速化したりすることもできます。

simulateTouchEvents(<object>, true); // ignore events on childs

これが私が書いたコードです。私はいくつかの素晴らしいトリックを使用して物事の評価をスピードアップしました(コードを参照)。

function simulateTouchEvents(oo,bIgnoreChilds)
{
 if( !$(oo)[0] )
  { return false; }

 if( !window.__touchTypes )
 {
   window.__touchTypes  = {touchstart:'mousedown',touchmove:'mousemove',touchend:'mouseup'};
   window.__touchInputs = {INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,'input':1,'textarea':1,'select':1,'option':1};
 }

$(oo).bind('touchstart touchmove touchend', function(ev)
{
    var bSame = (ev.target == this);
    if( bIgnoreChilds && !bSame )
     { return; }

    var b = (!bSame && ev.target.__ajqmeclk), // Get if object is already tested or input type
        e = ev.originalEvent;
    if( b === true || !e.touches || e.touches.length > 1 || !window.__touchTypes[e.type]  )
     { return; } //allow multi-touch gestures to work

    var oEv = ( !bSame && typeof b != 'boolean')?$(ev.target).data('events'):false,
        b = (!bSame)?(ev.target.__ajqmeclk = oEv?(oEv['click'] || oEv['mousedown'] || oEv['mouseup'] || oEv['mousemove']):false ):false;

    if( b || window.__touchInputs[ev.target.tagName] )
     { return; } //allow default clicks to work (and on inputs)

    // https://developer.mozilla.org/en/DOM/event.initMouseEvent for API
    var touch = e.changedTouches[0], newEvent = document.createEvent("MouseEvent");
    newEvent.initMouseEvent(window.__touchTypes[e.type], true, true, window, 1,
            touch.screenX, touch.screenY,
            touch.clientX, touch.clientY, false,
            false, false, false, 0, null);

    touch.target.dispatchEvent(newEvent);
    e.preventDefault();
    ev.stopImmediatePropagation();
    ev.stopPropagation();
    ev.preventDefault();
});
 return true;
}; 

機能:最初は、シングルタッチイベントをマウスイベントに変換します。ドラッグする必要のある要素の要素内/要素によってイベントが発生したかどうかを確認します。input、textareaなどの入力要素の場合、翻訳はスキップされます。または、標準のマウスイベントがそれにアタッチされている場合は、翻訳もスキップされます。

結果:ドラッグ可能な要素のすべての要素がまだ機能しています。

幸せなコーディング、greetz、Erwin Haantjes


どのオブジェクトを渡すべきですsimulateTouchEvents(<object>, true);か?
Valay 2014年

たとえば、simulateTouchEvents($( '#yourid;)、true); またはSimulateTouchEvents(document.getElementById( 'yourid')、true); etc
Codebeat

私の別の質問リンクを見ていただけませんか???
Valay 2014年

使用threedubmedia.com/code/event/drag及び無効xまたは要素のY可動。この記事のコードを使用すると、スクロールバーを「スクロール」できます。しかし、携帯電話のページにはすでにスクロールバーが表示されているので、なぜこれを実行したいのかを理解してください。どうしたいのか分からない。成功!
Codebeat、2014年

列のドラッグアンドドロップと両方のスクロールを追加する必要があります。でtouchイベントをオンにするとchrome、テーブルをスクロールできません。モバイルでもです。
Valay 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.