web-dev-qa-db-ja.com

jQueryのドラッグアンドドロップ-ドロップ可能の外側のドロップの確認

別の質問でこれが回答された場合、申し訳ありませんが、私の問題に固有の回答を見つけることができませんでした!

私は、jQueryのドラッグ可能オブジェクトが正当なドロップ可能オブジェクトの外にドロップされているかどうかをテストしようとしています。これは通常、ドラッグ可能なオブジェクトを元に戻すことで90%の時間で解決されますが、私はそれをしたくありません。代わりに、ドラッグ可能物がドロップ可能物にドロップされた場合(素晴らしい動作です!)、可能性のあるすべてのドロップ可能物の外にドロップされた場合(現在、私を良くしています!).

手短に:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    stop: function()
    {
        // need some way to check to see if this draggable has been dropped
        // successfully or not on an appropriate droppable...
        // I wish I could comment out my headache here like this too...
    }
});

私は本当に明白な何かを見逃しているような気がします...助けてくれてありがとう!

36
Chris Kempen

Droppableのdropイベントはdraggableのstopイベントの前に発生するため、次のようにdropイベントでドラッグされる要素にフラグを設定できると思います。

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        ui.helper.data('dropped', true);
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    start: function(event, ui) {
        ui.helper.data('dropped', false);
    },
    stop: function(event, ui)
    {
        alert('stop: dropped=' + ui.helper.data('dropped'));
        // Check value of ui.helper.data('dropped') and handle accordingly...
    }
});
53
Luke Girvin

あなたはすでに答えを得ているようです。とにかく私は今日この同じ問題を抱えていたので、この方法で解決しました。

var outside = 0;

// this one control if the draggable is outside the droppable area
$('#droppable').droppable({
    accept      : '.draggable',
    out         : function(){
        outside = 1;
    },
    over        : function(){
        outside = 0;
    }
});

// this one control if the draggable is dropped
$('body').droppable({
    accept      : '.draggable',
    drop        : function(event, ui){
        if(outside == 1){
            alert('Dropped outside!');
        }else{
            alert('Dropped inside!');
        }
    }
});

ドラッグ可能のオプションを変更できなかったので、それが必要でした。そのため、ドロップ可能のみで作業する必要がありました(素晴らしい FullCalendar プラグイン内で必要でした)。 droppablesの「貪欲な」オプションを使用すると問題が発生する可能性がありますが、ほとんどの場合は機能するはずです。

PS:私の悪い英語でごめんなさい。

EDIT:提案されたように、jQuery.dataを使用してバージョンを作成しました。ここにあります: jsfiddle.net/Polmonite/WZma9/

とにかくjQuery.dataのドキュメントには次のように書かれています:

Internet Explorerではexpandoプロパティを介したデータの添付が許可されていないため、このメソッドは現在、XMLドキュメントのデータ設定に対するクロスプラットフォームサポートを提供していないことに注意してください。

(IE 8より前)では動作しないことを意味します)

EDIT 2:@Darin Petersonが述べたように、以前のコードは複数のドロップエリアでは機能しません。これで問題が解決するはずです: http://jsfiddle.net/Polmonite/XJCmM/

EDIT 3:EDIT 2の例にはバグがあります。 「Drag me!」をドラッグすると下部のドロップ可能に、次に「ドロップミーも」を上部のドロップ可能にドロップしてから、「ドラッグミーも」を外側にドロップすると、「内側にドロップしました!」したがって、使用しないでください。

EDIT 4:@Aleksey Gorが述べたように、Edit 2の例は間違っていました。実際には、すべてのドラッグ可能/ドロップ可能をループする方法を説明するための例に過ぎませんでしたが、実際にはアラートメッセージを削除するのを忘れていたため、かなり混乱していました。 ここ 更新されたフィドル。

9
Polmonite

droppable要素のイベント "out"を使用してみてください。

これは ドキュメント です

「このイベントは、受け入れられたドラッグ可能オブジェクトがこのドロップ可能オブジェクトの許容範囲内でドラッグアウトされるとトリガーされます。」私が正しい場合、これはあなたが必要とするものです。

また、ページ全体に要素オーバーレイを作成することもできます。要素がそこにドロップされると、イベントが発生します。最高ではありませんが、それを行う唯一の方法だと思います。これらのイベントを発生させるには、他の「ドロップ可能な」アイテムが必要だからです。

4
ggzone

次の例の利点は、ドロップ可能なコードを変更したり、知る必要がないことです

ドラッグ可能な復帰プロパティには、function(value){}を含めることができます。値が引数として渡され、ヘルパーが要素にドロップされた場合(ドロップ要素)を示します。要素にドロップされなかった場合(外部ドロップまたは受け入れられない場合)は 'false'を示します。

注:ヘルパーに復帰するかしないか(true/false)を伝えるために、その復帰関数から正しいブール値を返す必要があります。 Trueは、はい、ヘルパーをスローモーション(すぐに使用可能)に戻すことにより、元の位置に戻すことを意味します。 Falseはいいえを意味し、ヘルパーを突然削除します。復帰プロパティを「無効」に設定することは、言うことのショートカットです

  • 「はい、外に落としてヘルパーを元に戻す」
  • 「いいえ、ドロップ可能な要素にドロップして受け入れたら、すぐにヘルパーを殺します」。

私の推測では、開始イベント中にdataプロパティを使用してドラッグ可能なコンテナに現在のUIヘルパーを追加できます。次に、データプロパティから関数revertで取得します。次に、ヘルパーにプロパティを追加し、ドロップされたかどうかを示します。その後、最終的に停止イベントで、このデータプロパティ値を確認し、意図したとおりに実行します。

ドラッグ可能のイベント/関数呼び出しの順序:start-revert-stop

これは一例です。

jQuery('#draggable').draggable(
{
    start: function(event, ui) {
        $(this).data('uihelper', ui.helper);
    },
    revert: function(value){
        var uiHelper = (this).data('uihelper');
        uiHelper.data('dropped', value !== false);
        if(value === false){
             return true;
        }
        return false;
    },
    stop: function(event, ui)
    {
        if(ui.helper.data('dropped') === true){
            // handle accordingly...
        }
    }
});

復帰関数でtrueを返すこともでき、ui.helper.remove()のdata( 'dropped')値に応じて、停止イベント中にヘルパーを削除することもできます。または、まだ悪い日がある場合は、CSS3で爆発させることもできます;)

1
Bogmag

古い質問と古い回答は、この「可能性のある」新しいソリューションであることを意味しています。また、質問が述べているように、ドラッグ可能がドロップ可能の外にドロップされたかどうかを知りたいかもしれません。私にとって、少なくとも95%のケースでは、IFをあまり気にしません。発生したときに変更を加えずに元の状態に戻したいだけです。

revertを文字列invalidに設定すると、追加のコードやファンキーな操作を行うことなく、目的の動作を実現できます。

$( '#draggable' ).draggable({
    revert: "invalid",
    stop: function( event, ui )
    {
       // whatever
    }
});

繰り返しになりますが、「ドロップ可能物の外にドロップされた場合」はわかりませんが、それが発生した場合は初期状態に戻ります。

0
Chris Ostmo

移動するオブジェクトのcssクラスからこれを非常に簡単に理解できるため、採用したソリューションを追加します。

jQuery('#draggable').draggable({
  stop: function(event, ui) {
    if (ui.helper.hasClass('ui-draggable-dragging')) {
      console.log('dropped out');
    } else {
      console.log('dropped successfully');
    }
  }
});
0
coorasse