2

ドロップ可能なものとして使用しようとしている div のかなり長いリストがありますが、現在のドラッグ可能な要素を受け入れないすべてのドロップ可能なものを非表示にしたいと考えています。

http://jsfiddle.net/N3uh3/に例を掲載しました

基本的に、「Drag A」要素をドラッグすると、すべての「Droppable B」要素が非表示になり、正しい要素にドロップできるようになり、これはうまく機能します。

ただし、「Drag B」要素をドラッグすると、すべての「Droppable A」要素が非表示になりますが、残りのドロップ領域はドラッグ可能なアイテムを受け入れません。「Droppable B」要素の元の場所にアイテムをドロップすると、(要素の位置が移動したとしても) 正しくドロップされます。「visibility: hidden;」を使用すると 「display:none」の代わりに、要素が移動しないため、これも機能します。

これが理にかなっていることを願っています-ドロップ可能な領域が要素の元の位置に設定されているようです....これを回避する方法はありますか?

.lhs { width: 40%; float:left; }
.rhs { width: 40%; float:right; }
.lhs div { margin: 4px; }
.a { background-color: green; }
.b { background-color: red; }
.ui-state-highlight { background-color: yellow; }
.dropZones .ui-droppable { display: none; }
.dropZones .ui-state-highlight { display: block; }
.currentDropZone { display: block; }

<div class="wrapper">
    <div class="lhs">
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
    </div>
    <div class="rhs">
        <div class="a">Drag A</div>
        <br />
        <div class="b">Drag B</div>
    </div>
</div>


$(document).ready(function(){
    $('.rhs div').draggable({
        helper: function (e,ui) {
            // this sets the clone to be a child of the body - fixing overflow:auto problems on divs!
            return $(this).clone().appendTo('body').css('zIndex',5).show();
        }, 
        revert: 'invalid',
        cursor: 'move',
        start: function(){
            //$('.lhs').addClass('dropZones');    // immediately hides so doesn't get the ui-state-highlight class'

            // give a quick period of time then add the class
            setTimeout(function() { $('.lhs').addClass('dropZones'); }, 250);
        },
        stop: function(){
            $('.lhs').removeClass('dropZones');
        },
    });

    $('.lhs div').each(function(){
        $(this).droppable({
            greedy: true,
            activeClass: 'ui-state-highlight',
            accept: '.' + $(this).attr('class'),
            drop: function(event, ui) {
                $(this).append($(ui.draggable).clone());
            },
            activate: function(){
                $(this).addClass('currentDropZone');
            },
            deactivate: function(){
                $(this).removeClass('currentDropZone');
            }

        });
    });
});

前もって感謝します!

4

1 に答える 1

3

問題は、非アクティブなドロップ可能オブジェクトを非表示にすると、要素の流れとアクティブなドロップ可能オブジェクトの位置が変わることです。遅延イベントが発生するまでに、ドロップ可能な絶対位置が jQuery UI によって既にキャッシュされており、マウス ボタンを放したときにそれがチェックされます。元の例では、表示されているリストのすぐ下にあるドロップゾーンBの古い位置にドラッグすると、ドロップできます。B

refreshPositions: true迅速かつ簡単な解決策は、ドラッグ可能なオプションを使用して、マウスを移動するたびにドロップ可能な位置を再計算するよう jQuery UI に指示することです。ドキュメントから:

refreshPositions : ブール値

true に設定すると、すべてのドロップ可能な位置がすべてのマウス移動で計算されます。注意: これにより、非常に動的なページの問題が解決されますが、パフォーマンスが大幅に低下します。

デモを更新しました: http://jsfiddle.net/N3uh3/1/

これは簡単な修正ですが、私の提案は、アイテムを非表示にするときに、に依存するのではなく、独自のロジックを作成することsetTimeout()です。

mousedown表示されているドロップ可能オブジェクトのみがアクティブ化されるため、アイテムのイベントのように、ドロップ可能オブジェクトを受け入れるリストを jQuery UI が作成する前に、非表示ロジックを追加します。次に、独自のカスタム コードを実行して、不要なドロップ可能オブジェクトを非表示にすることができます。そのため、位置をキャッシュする場合、それらは正しくなり、マウス移動ごとにキャッシュを更新する必要がなくなります。あなたが持っているドロップ可能アイテム。

于 2011-06-02T17:16:24.470 に答える