2013-09-06 16 views
8

Po pierwsze, wiem, że to pytanie zostało zadane wcześniej, zarówno na tej stronie, jak i na innych stronach, ale odpowiedzi są tylko śmieciami do mojego scenariusza (jeśli nie są to całkowicie śmieci) oraz (przynajmniej na pytanie tutaj: jQuery UI drop event of droppable fires on sortable), propozycja polega na całkowitym wyłączeniu .sortable, co z pewnością nie jest tym, co chcę zrobić.Zdarzenie upuszczania kropli jQuery UI droppable widget wypalanie dwa razy

Dobra, mam tego jQuery (należy pamiętać, jeśli wszelkie opcje lub identyfikatory html wyglądać głupio, to tylko do testów, więc mogę spróbować i rysunek to):

$(function() { 
    $("#sortable").sortable({ 
     revert: true 
    }); 
    $("#draggable, #draggable2").draggable({ 
     connectToSortable: "#sortable", 
     helper: "clone", 
     revert: "invalid" 
    }); 

    $("#sortable").droppable({ 
     drop: function (event, ui) { alert("done been triggered."); } 
    }); 

    $("ul, li").disableSelection(); 
}); 

I tu jest ważny znaczniki:

<div class="objectPaletteHolder"> 
    <ul> 
     <li id="draggable" class="ui-state-highlight">Drag me down</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, also</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, as well</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight click">Drag this down, click</li> 
     <li id="draggable2" class="ui-state-highlight clicky">Drag this down, clicky</li> 
    </ul> 
</div> 
<div class="editContainer"> 
    <ul id="sortable"> 
     <li class="ui-state-default">Item 1</li> 
     <li class="ui-state-default">Item 2</li> 
     <li class="ui-state-default">Item 3</li> 
     <li class="ui-state-default">Item 4</li> 
     <li class="ui-state-default">Item 5</li> 
    </ul> 
</div> 

nie mam nakładających sortable div lub coś podobnego, i myślę, że rozumiem „dlaczego” tak się dzieje (? bo sortable dostaje draggables właściwości domyślnie), po prostu nie mogę s Zrobić cokolwiek na ten temat.

Problem, oczywiście, jest to, że ...

drop: function (event, ui) { alert("done been triggered."); } 

... jest uruchamiany dwa razy, gdy jest ona potrzebna tylko raz.

Sądzę, że byłoby proste rozwiązanie tego problemu, ponieważ gdyby ten problem wymagał mnóstwa złożonych skryptów do naprawienia, wtedy uważałbym, że te konkretne widżety jquery nie byłyby warte wszystkich kłopotów. Być może jestem po prostu zdezorientowany?

+0

Co z skrzypcami? – Itay

+1

@Itay Zgodnie z życzeniem: http://jsfiddle.net/dMen8/6/ – VoidKing

Odpowiedz

19

Jest to znany problem polegający na używaniu zarówno sortable, jak i droppable na tym samym elemencie.

Zamiast tego można użyć zdarzenia sortable 'receive.

jsFiddle Demo

$("#sortable").sortable({ 
     revert: true, 
     receive: function (event, ui) {  
      alert("receive been triggered."); 
     } 
}).droppable({ }); 
+0

omg, właśnie o to chciałem. Przeszedłem przez różne wydarzenia między trzema różnymi widżetami, ale chyba nie widziałem "odbierania" lub nie sądziłem, że odnosi się ono do tego, o co prosiłem. W każdym razie (ta odpowiedź + ty = bomba-diggity). Dzięki! – VoidKing

+0

Fajnie tylko zauważ, że jest on podłączony do sortowalnego, a nie do droppable :) – Itay

+0

Rzeczywiście. Zauważyłem też, że po '.sabable' masz załączone' .droppable ({}) '. Czy powinno to być zrobione osobno? – VoidKing

-2

Może jestem trochę zbyt późno, ale napisałem to mam nadzieję, że to pomoże ktoś. To jest kod, którego używam. Zasadniczo, jeśli funkcja jest wywoływana dwa razy, odstęp między nimi powinien być szybki (szybciej niż zwykle robią ludzie), więc ustawiam liczbę na 200 milisekund.

Użyłem localStorage, aby ustawić zmienną o nazwie "last_call". Czas wywołania tej funkcji. Podczas następnego połączenia sprawdzimy, czy funkcja została wywołana wcześniej. Jeśli nie został wywołany, funkcja będzie nadal wykonywana. Jeśli został wywołany, sprawdzimy, kiedy ostatnio był wywoływany. Jeśli został wywołany w ciągu 200 milisekund (co oczywiście wywołanie urządzenia, a nie połączenie z człowiekiem), nie będziemy go ponownie wywoływać.

var d = new Date(); 
    var this_time = d.getTime(); 
    if (localStorage.getItem("last_call") != null) 
    { 
     if ((this_time - parseInt(localStorage.getItem("last_call"))) < 100) 
     { 

      return; 
     } 

    } 
    localStorage.setItem("last_call", this_time); 
+3

Nie rób tego ... – Javier

+0

Czy możesz wyjaśnić, dlaczego? – codingpuss

+0

@ codingpuss w zasadzie dlatego, że wygląda jak własna zwariowana implementacja setTimeout(). Ale nawet z setTimeout() będzie to hack, ale nie schludne rozwiązanie. – walv

0

Miałem podobny problem. Były 2 elementy zrzucane, jedna z nich miała względną pozycję, a druga - absolutna. Nie były zagnieżdżone, ale część tej z absolutną pozycją znajdowała się nad częścią z pozycją względną (w dokumentach jQuery nazywa się to "przecinają się"). Kiedy przeniosłem element przeciągalny do "bezwzględnego" droppable, zdarzenie drop zostało wywołane dwukrotnie. Szukałem kilku dni, ale nie znalazłem żadnego rozwiązania.

Potem zdecydowałem się na proste ogólne obejście. Wygląda niezbyt atrakcyjnie, ale pomoże to w każdej sytuacji przy wystrzeliwaniu 2 zdarzeń upuszczenia.

drop: function(e, ui) { 
    if (! $('.already-dropped').length) { 
     $('body').addClass('already-dropped'); 
     setTimeout(function() { 
      $('.already-dropped').removeClass('already-dropped'); 
     }, 100); 
     // callback code... 
    } 
} 
Powiązane problemy