2011-06-02 51 views
2

我有一個很長的div列表,我試圖用它作爲droppable的 - 但我想隱藏所有不接受當前的拖放可拖動元素。jQuery Droppables - 隱藏'不活動'拖放區域時的問題

我已經把一個例子了在http://jsfiddle.net/N3uh3/

基本上,如果我拖「拖一個」元素,將隱藏所有「可放開B」元素,讓我落到正確的元素,這工作得很好。

但是,如果我拖動'拖動B'元素,它將隱藏所有'Droppable A'元素,但其餘的拖放區域不接受我的可拖動項目。如果我將物品放在「Droppable B」元素的原始位置,則它會正確下落(即使元素的位置已移動)。如果我使用「可見度:隱藏的」而不是「顯示:無」,這也適用於元素不移動。

我希望這是有道理的 - 似乎可以將可投放區域設置爲元素的原始位置....是否有解決方法?

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

     }); 
    }); 
}); 

在此先感謝!

回答

3

問題是隱藏不活動的droppables會改變活動元素的流動和位置。當你的延遲事件觸發時,絕對可丟棄的位置已經被jQuery UI緩存了,這就是你放開鼠標按鈕時所檢查的內容。在原始示例中,如果將其拖動到B下拉列表的舊位置(即正好位於可見列表下方),仍然可以放下B

一個快速而簡單的解決方案是告訴jQuery UI重新計算每個鼠標移動的拖放位置,方法是使用拖動表上的refreshPositions: true選項。從documentation

refreshPositions:布爾

如果設置爲true,所有可放開 位置計算出每個 鼠標移動。注意:這可以在高動態頁面上解決問題 ,但 會顯着降低性能。

您更新演示:http://jsfiddle.net/N3uh3/1/

這是速戰速決,但我的建議是隱藏在你的項目的時候,而不是依靠setTimeout(),其中隱藏之前增加了一個明顯的惱人的滯後,彌補自己的邏輯你的droppables。

由於只顯示了可拖動對象,因此我會在jQuery UI之前添加我的隱藏邏輯,甚至有可能建立一個可接受可拖放對象列表,如項目上的mousedown事件。然後,您可以執行自己的自定義代碼來隱藏不需要的可拖放對象,因此,當涉及到緩存位置時,它們將是正確的,並且不需要每次移動鼠標時刷新緩存,這可能是一個昂貴的操作,具體取決於可以放棄的東西。

+0

Cheers DarthJDG。現在像魅力一樣工作 - 非常感謝! – Gus 2011-06-03 00:32:01

+0

對於任何有興趣的人 - 我已經使用達斯的建議更新了jsfiddle - 更好! http://jsfiddle.net/N3uh3/ – Gus 2011-06-03 01:20:38