2010-11-04 9 views
8

To jest trochę niejasny problem, ale używam jQuery Sortables i próbuję uzyskać dwie dobrze połączone ze sobą listy, gdy jeden z nich jest ustawiony jako fixed. Wszystko działa dobrze, dopóki nie przewiniesz strony tak, że dwie listy zostaną umieszczone jeden na drugim. Wtedy wydaje się, że listy nie mają pojęcia, który z nich powinien otrzymać przedmiot, który jest przeciągany, co oznacza, że ​​pojawia się mnóstwo zdenerwowania, które pojawia się/znika na każdej liście.Radzenie sobie z nakładającymi się listami sortowalnych jQuery

Wygląda na to, że obie listy obsługują zdarzenia myszy/sortowania, ponieważ element, który jest przeciągany, znajduje się technicznie na obu listach, ale chcę, aby nałożona lista (np. position: fixed) połknęła zdarzenia tak, że podstawowa lista nie próbuje odebrać przedmiotu.

Oto minimalne przykładowy kod:

<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> 

Więc pytanie brzmi, jak mogę to naprawić?

+0

Zanotuj kod biblioteki, dowiedz się, jak działa używana funkcja, a następnie powinieneś być w stanie rozwiązać problem. – aaaaaaaaaaaa

Odpowiedz

5

Skończyłem naprawiać ten problem, rozszerzając wbudowaną funkcję sortable, aby utworzyć fixedSortable, która wykrywa i selektywnie ignoruje najechanie kursorem na listy, gdy jest nałożona nakładka. Dla moich celów, po prostu mocno zakodowałem zasady, ponieważ to pasowało do moich potrzeb/ograniczeń czasowych, ale powinieneś być w stanie zrobić to całkowicie generycznym bez większego wysiłku.

Po pierwsze Oto kod (wyjaśnienie poniżej):

<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> 

Jeśli dostosowania tego samemu, trzeba zmienić dwa komentowane linie zaznaczone powyżej. Zasadniczo instrukcje if powinny mieć wartość true (a tym samym zwracać false), jeśli element, na którym znajduje się huśtawka (item.instance.element i containerCache.sortable.element), to , a nie nakładka i zdarzenie (this) pojawiające się w granicach nakładki. W ten sposób główna lista nigdy nie otrzyma zdarzeń w lokalizacji strony, na której znajduje się nakładka. Więc w tym kodzie główna lista nie otrzymuje żadnych zdarzeń, jeśli występują one w pierwszych 87 pikselach ekranu, ponieważ tam była moja stała nakładka (co nie jest do końca dokładne w tym przykładzie, ale mam nadzieję, że nadal ma sens).

+3

Nie wiem, czy jest to przydatne dla nikogo, ale Ive upuścił kod Alconja do JSBin, dzięki czemu można zobaczyć, że działa. http://jsbin.com/iqemid/2 all dzięki Alconja za ten kod ^^ – azzy81

2

Jest to bug myślę jesteś napotykają, a poprawka jest dużo prostsze:

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

+1

Myślę, że to ten sam błąd, ale sugerowana poprawka nie obejmuje wszystkich scenariuszy (w tym wspomnianego przez OP). Myślę, że prawdziwa poprawka wymaga określenia kontekstu stosowego wszystkich kontenerów z możliwością zrzutów pod kursorem i wybrania najwyższego kontenera pod względem porządku z. –

+0

Ah, prawdopodobnie prawda. Poprawka obejmuje tylko listy, które pokrywają się z powodu przepełnienia: ukryte, a nie z powodu kolejności Z. Wygląda na to, że najpierw musisz posortować kandydatów według porządku z, a następnie przejść przez nie, dopóki nie otrzymasz trafienia. – Jason

0

wpadłem na ten problem na stronie gdzie mam jedna lista pionowo nad drugim liście . Mimo że przepełnienie jest ustawione na ukryte, niewidoczne przepełnienie górnej listy nadal blokuje zdarzenie przeniesienia dla poniższej listy (można to potwierdzić, ustawiając przepełnienie na auto na górze listy, aby pomóc sobie wyobrazić nakładanie się). To jest problem z indeksem Z.

Moja poprawka było umieścić ten kod w sortable zdarzenia STOP:

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

Co ja robię tu jest wyraźnie ukrywając górne elementy listy, pozostawiając tylko top 5 widoczne tak, że nie ma DOM przesunięcie pokrywające się między górną i dolną listą.

Powiązane problemy