2010-11-04 14 views
8

這是一個晦澀難懂的問題,但我使用jQuery Sortables並試圖讓兩個連接的列表很好地協作,當一個被定位爲fixed時。這一切都正常工作,直到你滾動頁面一點,使兩個列表最終位於彼此的頂部。然後,這些列表似乎對於哪個應該接受被拖動的項目感到困惑,這意味着當每個列表出現/消失時,會發生一連串的抖動。處理重疊的jQuery可排序列表

它看起來像問題是,這兩個名單正在處理鼠標/排序活動自被拖動的項目在技術上是在兩個名單,但我要的是有重疊列表(即position: fixed之一)吞事件以便底層的主要列表不會嘗試接收該項目。

這裏是最小的代碼示例:

<html> 
<head> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script> 
    <style type="text/css"> 
     ul { list-style-type: none; padding: 0; float: left; } 
     li { margin: 5px; padding: 5px; width: 500px; border: solid 1px #F00; background-color: #FFF; } 
     #overlayed { position: fixed; top: 0; background-color: #000; margin: 20px; padding: 10px; } 
     #overlayed li { width: 50px; float: left; } 
    </style> 
    <script type="text/javascript"> 
     $(function() { 
      $("ul").sortable({ connectWith: "ul", opacity: 0.6 }).disableSelection(); 
     }); 
    </script> 
</head> 
<body> 
<div id="overlayed"> 
    <ul> 
     <li>Item X</li> 
     <li>Item Y</li> 
     <li>Item Z</li> 
    </ul> 
</div> 
<br/><br/><br/><br/><br/> 
<ul> 
    <li>Item 01</li> 
    <li>Item 02</li> 
    <li>Item 03</li> 
    <li>Item 04</li> 
    <li>Item 05</li> 
    <li>Item 06</li> 
    <li>Item 07</li> 
    <li>Item 08</li> 
    <li>Item 09</li> 
    <li>Item 10</li> 
    <li>Item 11</li> 
    <li>Item 12</li> 
    <li>Item 13</li> 
    <li>Item 14</li> 
    <li>Item 15</li> 
    <li>Item 16</li> 
    <li>Item 17</li> 
    <li>Item 18</li> 
    <li>Item 19</li> 
    <li>Item 20</li> 
    <li>Item 21</li> 
    <li>Item 22</li> 
    <li>Item 23</li> 
    <li>Item 24</li> 
    <li>Item 25</li> 
    <li>Item 26</li> 
    <li>Item 27</li> 
    <li>Item 28</li> 
    <li>Item 29</li> 
    <li>Item 30</li> 
</ul> 
</body> 
</html> 

所以現在的問題是,如何解決呢?

+0

潛入庫代碼,找出你正在使用的函數實際上是如何工作的,然後你應該能夠解決你的問題。 – aaaaaaaaaaaa 2010-11-04 01:47:47

回答

5

我最終通過擴展內置的sortable功能來創建fixedSortable來解決此問題,該功能檢測並選擇性地忽略在疊加到位時懸停在列表上。出於我的目的,我只是硬編碼規則,因爲這符合我的需求/時間限制,但是您應該能夠在不付出太多努力的情況下完全通用。

首先這裏的代碼(下文解釋):

<html> 
<head> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script> 
    <style type="text/css"> 
     ul { list-style-type: none; padding: 0; float: left; } 
     li { margin: 5px; padding: 5px; width: 500px; border: solid 1px #F00; background-color: #FFF; } 
     #overlayed { position: fixed; top: 0; background-color: #000; margin: 20px; padding: 10px; } 
     #overlayed li { width: 50px; float: left; } 
    </style> 
    <script type="text/javascript"> 
     (function ($, undefined) { 
      $.widget("ui.fixedSortable", $.ui.sortable, { 
       _init: function() { 
        this.element.data("sortable", this.element.data("fixedSortable")); 
        return $.ui.sortable.prototype._init.apply(this, arguments); 
       }, 
       _create:function() { 
        var result = $.ui.sortable.prototype._create.apply(this, arguments); 
        this.containerCache.sortable = this; 
        return result; 
       }, 
       _intersectsWithPointer: function (item) { 
//This line.... 
        if (item.instance.element.hasClass("main-list") && this.positionAbs.top + this.offset.click.top < $(window).scrollTop() + 87) { 
         return false; 
        } 
        return $.ui.sortable.prototype._intersectsWithPointer.apply(this, arguments); 
       }, 
       _intersectsWith: function(containerCache) { 
//Also this line.... 
        if (containerCache.sortable.element.hasClass("main-list") && this.positionAbs.top + this.offset.click.top < $(window).scrollTop() + 87) { 
         return false; 
        } 
        return $.ui.sortable.prototype._intersectsWith.apply(this, arguments); 
       } 
      }); 
     })(jQuery); 

     $(function() { 
      $("ul").fixedSortable({ connectWith: "ul", opacity: 0.6 }).disableSelection(); 
     }); 
    </script> 
</head> 
<body> 
<div id="overlayed"> 
    <ul> 
     <li>Item X</li> 
     <li>Item Y</li> 
     <li>Item Z</li> 
    </ul> 
</div> 
<br/><br/><br/><br/><br/> 
<ul class="main-list" > 
    <li>Item 01</li> 
    <li>Item 02</li> 
    <li>Item 03</li> 
    <li>Item 04</li> 
    <li>Item 05</li> 
    <li>Item 06</li> 
    <li>Item 07</li> 
    <li>Item 08</li> 
    <li>Item 09</li> 
    <li>Item 10</li> 
    <li>Item 11</li> 
    <li>Item 12</li> 
    <li>Item 13</li> 
    <li>Item 14</li> 
    <li>Item 15</li> 
    <li>Item 16</li> 
    <li>Item 17</li> 
    <li>Item 18</li> 
    <li>Item 19</li> 
    <li>Item 20</li> 
    <li>Item 21</li> 
    <li>Item 22</li> 
    <li>Item 23</li> 
    <li>Item 24</li> 
    <li>Item 25</li> 
    <li>Item 26</li> 
    <li>Item 27</li> 
    <li>Item 28</li> 
    <li>Item 29</li> 
    <li>Item 30</li> 
</ul> 
</body> 
</html> 

如果適應這個自己,你需要更改上面標明兩種註釋行。基本上if語句應該評估爲true(並因此返回false),如果項目被懸停(item.instance.elementcontainerCache.sortable.element)是而不是覆蓋和事件(this)發生在覆蓋範圍內。通過這種方式,主列表從不接收疊加層所在頁面位置的事件。所以在這段代碼中,如果主列表出現在屏幕的前87個像素中,主列表就不會收到任何事件,因爲這是我的固定覆蓋圖(這在這個愚蠢的示例中不太準確,但希望它仍然有意義)。

+3

不知道這對任何人都有用,但是我將Alconja的代碼放入JSBin,這樣你就可以看到它的工作。 http://jsbin.com/iqemid/2全部感謝Alconja代碼^^ – azzy81 2012-02-14 10:07:42

2

這是我想你遇到的bug,修復該問題簡單了很多:

http://bugs.jqueryui.com/ticket/7065

+1

我認爲這是同樣的錯誤,但是建議的修復並未涵蓋所有場景(包括OP提到的那個)。我認爲真正的修復需要確定光標下所有可放置容器的堆疊上下文,並根據z順序選擇最上面的容器。 – 2012-04-27 20:55:32

+0

啊,可能是真的。該修補程序僅涵蓋由於溢出而重疊的列表:隱藏的,不是由於z順序。看起來你需要先按z順序對候選人進行排序,然後遍歷它們,直到得到命中。 – Jason 2012-04-30 21:24:11

0

我遇到了一個頁面,在這裏我有一個垂直列表上方的第二列表上的這個問題。即使溢出被設置爲隱藏,頂部列表的不可見溢出仍然阻止其下方列表的移動結束事件(這可以通過在頂部列表中將溢出設置爲自動來確認以幫助可視化重疊)。這是一個Z指數問題。

我的修復是把這個代碼在排序停止事件:

//expliclty hide the overflow items 
$('.topList .item:gt(5)').hide(); 
$('.topeList .item:first').show(); 

我在做什麼在這裏被明確地躲在上面列表中的元素,只留下前5可見,所以不存在DOM頂部和底部列表之間的偏移重疊。