34

Moje przeprosiny, jeśli odpowiedź na to pytanie została udzielona w innym pytaniu, nie mogłem znaleźć odpowiedzi dotyczącej mojego problemu!jQuery przeciągnij i upuść - sprawdzanie, czy nie ma kropli poza zrzucanym

Próbuję sprawdzić, czy przeciąganie jQuery jest opuszczane poza legalnym droppachem. Zazwyczaj zostanie to rozwiązane w 90% przypadków poprzez cofnięcie przeciągania, ale nie chcę tego robić. Zamiast tego, chcę zrobić jedną rzecz, jeśli przeciągnięcie zostanie upuszczone na droppable (działa świetnie!), I coś innego, jeśli zostanie upuszczone poza wszystkie możliwe droppables (obecnie coraz lepiej mnie!).

W skrócie:

jQuery('#droppable').droppable(
{ 
    accept: '#draggable', 
    drop: function(event, ui) 
    { 
     // awesome code that works and handles successful drops... 
    } 
}); 

jQuery('#draggable').draggable(
{ 
    revert: false, 
    stop: function() 
    { 
     // need some way to check to see if this draggable has been dropped 
     // successfully or not on an appropriate droppable... 
     // I wish I could comment out my headache here like this too... 
    } 
}); 

czuję się jakbym brakuje czegoś naprawdę oczywiste ... z góry dzięki za wszelką pomoc!

Odpowiedz

52

Ponieważ Zdarzenie upuść droppable przed razie zatrzymać Draggable jest, myślę, że można ustawić flagę na elemencie przeciągane w przypadku rozwijanej tak:

jQuery('#droppable').droppable(
{ 
    accept: '#draggable', 
    drop: function(event, ui) 
    { 
     ui.helper.data('dropped', true); 
     // awesome code that works and handles successful drops... 
    } 
}); 

jQuery('#draggable').draggable(
{ 
    revert: false, 
    start: function(event, ui) { 
     ui.helper.data('dropped', false); 
    }, 
    stop: function(event, ui) 
    { 
     alert('stop: dropped=' + ui.helper.data('dropped')); 
     // Check value of ui.helper.data('dropped') and handle accordingly... 
    } 
}); 
+3

Bardzo, bardzo fajne rozwiązanie Luke, dzięki za to ... zadziałało jak czar! –

+0

Amazing but: Czy jest jakaś dokumentacja dla .data? Dla mnie to trochę zstępuje z nieba: 3 (czytaj: nie można znaleźć więcej informacji) – yoshi

+0

http://api.jquery.com/jQuery.data/ –

4

Spróbuj użyć zdarzenia "out" elementu droppable.

To documentation

„To zdarzenie jest wywoływane, gdy przyjął przeciągany jest wyciągnięty (w granicach tolerancji) to droppable”. Jeśli mam rację, to jest to, czego potrzebujesz.

Możliwe jest również utworzenie nakładki elementów na całej stronie. Jeśli element zostanie upuszczony, wystrzelisz swoje wydarzenie. Nie najlepszy, ale myślę, że to jedyny sposób, żeby to zrobić. Ponieważ do wywołania tych zdarzeń potrzebny jest inny "zrywalny" przedmiot.

+0

Hej, ggzone, dziękuję za szybką odpowiedź ... Byłoby idealnie, gdyby przeciągany przeciągany był z ważnego droppitu. Jeśli przeciągnięcie zostało przeciągnięte z pierwotnej pozycji, a następnie spadł gdzieś przypadkowo daleko od legalnego droppala, to to wydarzenie nigdy nie zostanie wystrzelone, o ile wiem! –

+0

Edytowałem swoją odpowiedź dla ciebie – ggzone

+0

Awesome, thanks ggzone ... jak powiedziałeś, prawdopodobnie nie najlepszy, a jeśli nie widziałeś jeszcze odpowiedzi zapewnionej przez Luke'a, myślę, że oferuje o wiele bardziej eleganckie rozwiązanie z tym samym wyniki! –

9

widzę, że macie już odpowiedź ; W każdym razie miałem ten sam problem już rozwiązany i to w ten sposób:

var outside = 0; 

// this one control if the draggable is outside the droppable area 
$('#droppable').droppable({ 
    accept  : '.draggable', 
    out   : function(){ 
     outside = 1; 
    }, 
    over  : function(){ 
     outside = 0; 
    } 
}); 

// this one control if the draggable is dropped 
$('body').droppable({ 
    accept  : '.draggable', 
    drop  : function(event, ui){ 
     if(outside == 1){ 
      alert('Dropped outside!'); 
     }else{ 
      alert('Dropped inside!'); 
     } 
    } 
}); 

co potrzebne, bo nie mogę zmienić opcje moich draggables, więc musiałem pracować tylko z droppables (musiałem go wewnątrz wspaniała wtyczka FullCalendar). Przypuszczam, że może to powodować problemy przy użyciu "chciwej" opcji droppables, ale w większości przypadków powinno działać.

PS: przepraszam za mój zły angielski.

EDYCJA: Zgodnie z sugestią, stworzyłem wersję przy użyciu jQuery.data; można je znaleźć tutaj: jsfiddle.net/Polmonite/WZma9/

Zresztą dokumentacja jQuery.data powiedzieć:

Należy zauważyć, że metoda ta obecnie nie przewiduje wsparcie wieloplatformowe ustalania danych na dokumentach XML, jak Internet Explorer nie pozwala na dane do dołączenia za pośrednictwem właściwości expando.

(co oznacza, że ​​nie działa na IE przed 8)

EDIT 2: Jak zauważono @Darin Peterson, poprzedni kod nie pracować z więcej niż jednej powierzchni kropli ; powinno to naprawić ten problem: http://jsfiddle.net/Polmonite/XJCmM/

EDIT 3: Przykład z edycji 2 ma błąd. Jeśli przeciągnę "Przeciągnij mnie!" na dół, a następnie upuść "Przeciągnij mnie też" do górnej droppable, a następnie upuść "Przeciągnij mnie też" na zewnątrz, ostrzeże "Upuszczono w środku!" Więc nie używaj go.

EDYCJA 4: Jak zauważył @Aleksey Gor, przykład w Edit 2 był błędny; w rzeczywistości był to raczej przykład do wyjaśnienia, w jaki sposób można przechodzić przez wszystkie draggables/droppables, ale tak naprawdę zapomniałem usunąć komunikaty ostrzegawcze, więc było to dość mylące. Here zaktualizowane skrzypce.

+0

Ładne i proste! To dobre rozwiązanie, szczególnie gdy nie masz dostępu do draggables. Zastanawiam się, teraz myśląc o możliwych problemach z zasięgiem, czy mógłbyś użyć danych '$ (" # droppable "). (" Na zewnątrz ", prawda)," aby "nosić" stan zmiennej bardziej elegancko? Dobre rozwiązanie! Dziękuję za twój wkład! :) –

+1

Pewnie. Dodałem wersję, używając jQuery.data do odpowiedzi;) W każdym razie oznacza to brak IE7 (na wypadek, gdyby ktoś się tym przejmował). – Polmonite

+0

Genialny! Dzięki za badania i rozszerzoną odpowiedź! +1 –

1

Zaletą poniższym przykładzie jest to, że nie trzeba zmieniać lub wiedzieć o kodzie droppable:

możliwa do przesunięcia nieruchomość revert może mieć Function (value) {}. Wartość jest przekazywana jako argument, wskazując, że pomocnik został upuszczony na element (element drop), lub "false", jeśli nie został upuszczony na element (upuść na zewnątrz lub nie został przyjęty).

Uwaga: trzeba przywrócić prawidłową wartość bool z tego revert-funkcji, aby powiedzieć pomocnika powrócić lub nie (prawda/fałsz). Prawda oznacza, że ​​tak, zabierz pomocnika z powrotem do pierwotnej pozycji , przesuwając go z powrotem w zwolnionym tempie (po wyjęciu z pudełka). Fałsz oznacza, że ​​nie, po prostu należy nagle usunąć pomocnika. Ustawienie właściwości przywrócić „nieważny”, jest skrótem od mówiąc

  • „tak, jeśli spadła na zewnątrz, a następnie powrócić pomocnika”
  • „nie, jeśli spadła na droppable elementu i akceptowane, a następnie zabić pomocnik od razu ".

Domyślam się, że można dodać aktualną ui pomocnika do Draggable pojemnika z właściwości data zdarzenia podczas startu. Następnie podnieś go w funkcji przywracania z właściwości data. Następnie dodaj właściwość do pomocnika, wskazując, czy została upuszczona, czy nie. Następnie ostatecznie w zdarzeniu stop, sprawdź tę wartość właściwości danych i wykonaj to, co zamierzałeś.

Kolejność zdarzeń/funkcja wymaga przeciągany: uruchomienie przywrócić stop

Może to być na przykład:

jQuery('#draggable').draggable(
{ 
    start: function(event, ui) { 
     $(this).data('uihelper', ui.helper); 
    }, 
    revert: function(value){ 
     var uiHelper = (this).data('uihelper'); 
     uiHelper.data('dropped', value !== false); 
     if(value === false){ 
      return true; 
     } 
     return false; 
    }, 
    stop: function(event, ui) 
    { 
     if(ui.helper.data('dropped') === true){ 
      // handle accordingly... 
     } 
    } 
}); 

Można nawet wrócić prawda w funkcji revert i po prostu usunąć helper podczas zdarzenia stop, w zależności od wartości danych ("dropped") za pomocą funkcji ui.helper.remove(). Możesz nawet eksplodować przy pomocy CSS3, jeśli nadal masz zły dzień;)

Powiązane problemy