Jak zrobić jQuery Drag&Drop plugin w 5 minut




Jak zrobic jQuery Drag&Drop plugin w 5 minut

Plan jest prosty – zrobić plugin do jQuery, który umożliwi wykonanie drag & drop na dowolnym elemencie, by jednocześnie nie musieć korzystać z dostępnych rozbudowanych wtyczek.

A wszystko w dosłownie 5 minut :)

Działanie

Działanie pluginu ma polegać na możliwości przeniesienia dowolnego elementu, pod który będzie podpięty plugin. Przenoszenie będzie aktywowane poprzez kliknięcie na element, następnie zostanie on wyśrodkowany względem kursora. Poruszanie kursorem będzie powodowało przemieszczanie się elementu po ekranie. Aby zatrzymać przenoszenie elementu należy znów kliknąć na element – który powinien zostać opuszczony w miejscu w którym kursora.

Zobacz DEMO

Szablon pluginu

Jak w każdym pluginie należy zacząć od podstaw, czyli od szablonu. W naszym przypadku będzie on naprawdę prosty. Plugin będzie się nazywał dragdrop i taką właśnie funkcje będzie należało wywołać na elemencie na którym ma zostać wywołana funkcja. Do zmiennej globalnej element zostanie zapisany element wywołania funkcji:

  1. (function($){
  2.  
  3. $.fn.dragdrop = function(){
  4.     var element = this;
  5. })(jQuery);

Samo wywołanie będzie wyglądało następująco:

  1. $(document).ready(function(){
  2.     $("#box").dragdrop();
  3. });

Eventy i funkcje

Mając już gotowy szkielet pluginu, należy rozłożyć schemat działania na czynniki pierwsze. Flaga started będzie sygnalizować, czy należy poruszać elementem. Funkcje bindMove() i unbindMove() będą realizowały poruszanie i opuszczanie elementu, natomiast highlight() będzie odpowiedzialna za oznaczenie aktualnie przenoszonego elementu.

Dodatkowo do elementu został podpięty event nasłuchujący jego kliknięcie i w zależności od tego, czy flaga started jest true czy false, wywoływana jest funkcja przenosząca lub opuszczająca element.

  1. $(element).bind("click", function(e) {
  2.     if(!started){
  3.         bindMove();
  4.         started=true;
  5.     }else{
  6.         unbindMove();
  7.         started=false;
  8.     }
  9. });

Na tym etapie całość wygląda następująco:

  1. (function($){
  2. $.fn.dragdrop = function(){
  3.  
  4. var element = this;
  5. var started = false;
  6.  
  7.     $(element).bind("click", function(e) {
  8.         if(!started){
  9.         bindMove();
  10.         started=true;
  11.     }else{
  12.         unbindMove();
  13.         started=false;
  14.     }
  15. });
  16.  
  17.  
  18. function bindMove(){
  19. };
  20.  
  21. function unbindMove(){
  22. };
  23.  
  24. function highlight(display){
  25. }
  26.  
  27. };
  28.  
  29. })(jQuery);

Przenoszenie elementu

Przenoszenie elementu jest właściwie ciągłym zmienianiem stylów CSS, wywoływanym na zdarzenie mousemove, na elemencie którego dotyczy wywołanie funkcji. W pierwszej kolejności wywoływana jest funkcja e.preventDefault();, która zapobiega wywołaniu się domyślnych zdarzeń, np. scrollowaniu podczas przenoszenia elementu.

Następnie z eventu pobierane są współrzędne x i y położenia kursora i na tej podstawie wyliczana jest współrzędna x i y która ma zostać dodana do stylów CSS elementu w postaci wartości left i top. Dodatkowo ustawiany jest atrybut position na absolute, w przypadku gdyby nie był wcześniej nadany. Wyśrodkowanie elementu względem kursora jest realizowane za pomocą wzoru: WSPÓŁRZĘDNA_X – (DŁUGOŚĆ/2). Analogicznie jest z wysokością.

  1. function bindMove(){
  2. $(document).bind("mousemove", function(e) {
  3.     e.preventDefault();
  4.     var x,y;
  5.     var orig = e.originalEvent;
  6.  
  7.     x = orig.clientX;
  8.     y = orig.clientY;
  9.    
  10.     $(element).css({top: y-$(element).height()/2, left: x-$(element).width()/|>2, position: 'absolute'});
  11.  
  12. });
  13.  
  14. highlight(true);
  15.  
  16. };

Dodatkowo wywoływana jest funkcja highlight(true), która oznacza wybrany element dodając żółtą ramkę informującą, że może być on poruszany. Wywołanie funkcji z wartością false powoduje usunięcie owej ramki.

  1. function highlight(display){
  2.     if(display){
  3.         $(element).css({border : '1px solid yellow'});
  4.     }else{
  5.         $(element).css({border : 'none'});
  6.     }
  7. }

Opuszczanie elementu

Opuszczanie elementu sprowadza się do przestania nasłuchiwania na event mousemove oraz usunięcia ramki:

  1. function unbindMove(){
  2.     $(document).unbind("mousemove");
  3.     highlight(false);
  4. };

A co z urządzeniami dotykowymi?

Pozostaje jeszcze jedynie zapytać co z urządzeniami dotykowymi? Otóż niestety powyższy plugin nie zadziała na ipadzie, smartfonie czy jakimkolwiek urządzeniu dotykowym.

Aby jednak dostosować plugin do urządzeń dotykowych, wystarczy nieco przerobić eventy i ich obsługę. Do statu pluginu do eventu click należy dodać kolejny touchstart, następnie do mousemove, dodać touchmove, zarówno w funkcji bindMove() jak również w unbindMove(). Dodatkowo zmienia nam się sposób czytania pozycji kursora (w tym wypadku miejsca dotyku), co musimy uwzględnić w funkcji bindMove():

  1. function bindMove(){
  2.   $(document).bind("touchmove mousemove", function(e) {
  3.     e.preventDefault();
  4.     var x,y;
  5.     var orig = e.originalEvent;  
  6.         if(orig.changedTouches==undefined){
  7.             x = orig.clientX;
  8.             y = orig.clientY;
  9.         }else{
  10.            x = orig.changedTouches[0].pageX;
  11.            y = orig.changedTouches[0].pageY;
  12.         }
  13.  
  14.     $(element).css({top: y-$(element).height()/2, left: x-$(element).width()/|>2, position: 'absolute'});
  15.  
  16. });
  17. highlight(true);
  18. };

Pozycja jest pobierana z orig.changedTouches, więc jeżeli wartość ta jest undefined, znaczy, że powinniśmy pobierać współrzędne w dotychczasowy sposób. W przeciwnym razie pobieramy współrzędne właśnie z tego obiektu.

Gotowy plugin

Tym sposobem mamy w pełni funkcjonujący plugin realizujący drag&drop:

  1. (function($){
  2.  
  3. $.fn.dragdrop = function(){
  4.  
  5. var element = this;
  6. var started = false;
  7.  
  8.     $(element).bind("touchstart click", function(e) {
  9.         if(!started){
  10.             bindMove();
  11.             started=true;
  12.         }else{
  13.                 unbindMove();
  14.                 started=false;
  15.         }
  16.     });
  17.  
  18.  
  19. function bindMove(){
  20.     $(document).bind("touchmove mousemove", function(e) {
  21.     e.preventDefault();
  22.     var x,y;
  23.     var orig = e.originalEvent;  
  24.         if(orig.changedTouches==undefined){
  25.                 x = orig.clientX;
  26.                 y = orig.clientY;
  27.         }else{
  28.                 x = orig.changedTouches[0].pageX;
  29.                 y = orig.changedTouches[0].pageY;
  30.         }
  31.  
  32.     $(element).css({top: y-$(element).height()/2, left: x-$(element).width()/|>2, position: 'absolute'});
  33.  
  34. });
  35.     highlight(true);
  36. };
  37.  
  38. function unbindMove(){
  39.     $(document).unbind("touchmove mousemove");
  40.     highlight(false);
  41. };
  42.  
  43. function highlight(display){
  44.     if(display){
  45.         $(element).css({border : '1px solid yellow'});
  46.     }else{
  47.         $(element).css({border : 'none'});
  48.     }
  49. };
  50.  
  51. };
  52.  
  53. })(jQuery);

Zobacz DEMO

Related Posts with Thumbnails
Prześlij dalej:
Digg Google Bookmarks reddit Mixx StumbleUpon Technorati Yahoo! Buzz DesignFloat Delicious BlinkList Furl

3 komentarze do “Jak zrobić jQuery Drag&Drop plugin w 5 minut”

To jest bardziej Click&Drag&Drop;)

commenter

W sumie to masz całkowita rację :)

Zostaw komentarz:

Imię (wymagane):
Email:
Strona www:
Komentarz (wymagany):
XHTML: W komentarzach możesz korzystać z nastepujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
-