JavaScript: Drag and Drop

Ostatnio, z ciekawości, jak istotne są różnice w implementacji pewnych mechanizmów w różnych przeglądarkach internetowych napisałem bibliotekę Drag and Drop (przenoszenie dowolnych elementów na stronie). Postanowiłem, że przedstawię ją i udostępnię w postaci do natychmiastowego użycia.

Z góry zaznaczam, że na tym etapie nie przedstawię opisu jak to zrobić, bo Kurs JS znajduje się na zupełnie innym etapie, aczkolwiek poruszymy wkrótce i tego typu zagadnienia.

Biblioteka jest prosta i oferuje podstawowe funkcjonalności. Pozwala przesuwać dowolny element o określonym id w dowolnym kontenerze – może to być jakiś element blokowy, czy też cały dokument.

Przykład użycia:

<div style="border: 10px solid #ADADAD; width: 400px; height:300px;">
	<div id="someContainer" style="background: #2E2E2E; width: 400px; height: 300px;">
		<div id="someElement" style="background: #E6E6E6; width: 100px; height: 100px;"><strong>przesuń mnie!</strong></div>
	</div>
</div>

<script type="text/javascript" src="dragndrop.js"></script>
<script>
<!--
DragnDrop.InitDrag($('someElement'), $('someContainer'));
-->
</script>

Jeśli chcemy, aby jakiś element mógł być przesuwalny, używamy tej funkcji DragnDrop.InitDrag:

DragnDrop.InitDrag(odnośnik do elementu przesuwanego, odnośnik do kontenera);

Funkcja $() pobiera odnośniki do elementów o podanym id w argumencie. Używając jej, DragnDrop dla danego elementu możemy otrzymać tak:

DragnDrop.InitDrag($(id elementu przesuwanego), $(id kontenera w ktorym element ma byc przesuwany);

Równie dobrze można to zrobić tak:

DragnDrop.InitDrag(document.getElementById(id elementu przesuwanego), document.getElementById(id kontenera w ktorym element ma byc przesuwany);

Jeśli chcemy, aby element przesuwał się w całym dokumencie, nie uzupełniamy drugiego argumentu.

Aby dodać wiele elementów, wielokrotnie używamy po prostu powyższej funkcji:

DragnDrop.InitDrag($('someElement'), $('someContainer'));
DragnDrop.InitDrag($('anotherElement'), $('anotherContainer'));
DragnDrop.InitDrag($('another2Element'), $('another2Container'));

Oczywiście możemy również usunąć element z listy elementów przesuwanych. Posłuży nam do tego funkcja DragnDrop.RemoveDrag(), która przyjmuje jeden argument, jakim jest identyfikator danego elementu:

DragnDrop.RemoveDrag('jakies_id');

I to w zasadzie na tyle. Do prostego użycia jak znalazł. Niepotrzebne są tutaj żadne frameworki. Wymaga się podstawowej wiedzy z zakresu użycia funkcji, aczkolwiek po wnikliwej lekturze Wprowadzenia do JS myślę, że większość taką posiada.

Powiem szczerze, że skrypt będę rozwijał dla swoich potrzeb i pewnie wkrótce opublikuje jakąś poprawioną jego wersję. W działaniu zobaczycie go w nowych projekcie, który tuż tuż. Jeśli spytacie natomiast, Ferrante, będzie takich skryptów więcej, to odpowiem, że tak, co jakiś czas będę wrzucał tutaj różne bajery typu biblioteki zmiany wielkości elementów i tak dalej. Oczywiście wszystkie pojawią się w kursie JS. Skrypty będą na licencji Creative Commons 2.5, co znaczy, że możecie ich używać komercyjnie i niekomercyjnie, prosi się tylko o zachowanie podpisu autora i brak modyfikacji.

Niektórzy z Was zapytają pewnie, dlaczego nie jQuery lub Prototype i jakiś plugin? Otóż odpowiedź na to pytanie dostaniecie już wkrótce! Szykuję skromną niespodziankę.

Ściągnij skrypt JS DragnDrop!

Komentarze

1

[…] kodzie. Ma to dość duże uzasadnienie, ale nie posypuje całkowicie głowy popiołem. Pisząć DragnDrop pomyślałem przez chwilkę, że dobrze, fajnie to wyszło w czystym JS, ale moja programistyczna […]

2

No cóż. Czekamy na tę “skromną” niespodziankę :P

Off
3

Nie mogę się doczekać niespodzianki;)

michal
4

Taka mała sugestia:
W funkcji Drag() proponuję najpierw sprawdzić, czy element przesuwany nie wyjedzie poza obszar i następnie go przesunąć, a nie na odwrót, gdzie występuje efekt migania przy przesuwaniu poza wskazanym obszarem. Może nie do końca piękny, ale poniższy kod obrazuje, co chciałem powiedzieć:
if ((position.x-DragnDrop.Left) = DragnDrop.Elements[DragnDrop.El.id].MaxRight)
{
DragnDrop.El.style.left = (DragnDrop.Elements[DragnDrop.El.id].MaxRight - parseInt(DragnDrop.El.offsetWidth))+"px";
}
else
{
DragnDrop.El.style.left = (position.x-DragnDrop.Left)+"px";
}
if ((position.y-DragnDrop.Top) = DragnDrop.Elements[DragnDrop.El.id].MaxBottom)
{
DragnDrop.El.style.top = (DragnDrop.Elements[DragnDrop.El.id].MaxBottom -parseInt(DragnDrop.El.offsetHeight))+"px";
}
else
{
DragnDrop.El.style.top = (position.y-DragnDrop.Top)+"px";
}

Przy okazji redukuje się liczba sprawdzeń warunku dla if’a ;).

kszana
5

Dzieki za uwage, poprawki naniose wkrotce :).

6

Mam pytanko:
Co zrobi,ć żeby te warstwy sie na siebie nie nakładały??

Dylew
7

a co w przypadku, gdy chcę mieć coś takiego

NAGŁÓWEK
TREŚĆ
STOPKA

i za pomocą NAGŁÓWKA poruszać tym wszystkim?

próbuję coś znaleźć na ten temat lub przykład, ale nie udaje mi się

juzwa
8

znaczniki ucieło
[div]
[div]NAGŁÓWEK[/div]
[div]TREŚÄ†[/div]
[div]STOPKA[/div]
[/div]

juzwa
9

Mam problem z rozwiązaniem następującej kwestii. W kontenerze umieszceone są 4 elemety. za pomocą d&d zamieniam je miejscami ale po przeładowaniu strony wracają do poprzedniego układu. W jaki sposób można zapisać nowo utworzony układ divów?

Paweł
10

Zapisz koordy w cookies :)

dumdas
11

A co wypadało by zmienić aby owy skrypt przemieszczał rodzica obiektu na którym jest wcisniety wskaźnik myszy wraz ze wszytskimi potomkami ktore nie beda posiadaly funkcji przemieszczania rodzica?? poprosu mozą łatwo szybko i przyjemnie przerobic ten skrypt na coś w stylu okienka explorera??

pepe
12

dumdas mógłbyś rozwinąć swój wpis o wpisaniu koordów w cookies??

Paweł
13

jak zrobić żeby te elementy były ustawiane obok siebie? bez nachodzenia jeden na drugim?

r1234
14

W IE nie działa kiedy element tworzy się dynamicznie w js. tutaj pojawia się błąd:
var border = parseInt(elArea.parentNode.style.borderWidth);
Można go w jakiś sposób wyeliminować?

presscot
15

ps juz po utworzeniu DIVa kiedy wczytuje funkcje draganddrop wyskakuje komunikat ze nie jest obiektem

?????

presscot
16

bardzo fajny kod, dzięki!!!

17

W skrypcie jest błąd. Problem pojawia się w IE przy wywołaniu metody DragnDrop.InitDrag(id) tylko z jednym parametrem (elementem który ma byc przesuwany). np. DragnDrop.InitDrag($(‘someElement’));
Martinos

Martinos
18

Hmmm, ja także mam problem ze zrobieniem tego przeciągania za uchwyt.

19

Witam.

Kod jest fajny i prosty do ogarnięcia, niestety pojawił mi się pewien problem gdy użyłem go w Firefoxie lun IE6.0. Otóż kiedy przeciąganymi obiektami mają być obrazki, pochwycenie obiektu przestaje działapłynnie a zaczyna następująco:
1). Klikam na obiekt i próbuję go przeciągnąć trzymając przycisk
2). Obiekt nie reaguje
3). Puszczam przycisk
4). Dopiero teraz obiekt przykleja się do kursora mimo iż nie trzymam myszy.
5). Klikam ponownie i obiekt odkleja się pozostając w nowym miejscu.
Jeżeli kliknę na obiekt ale nie ruszę myszą, to nie przykleja się on do niej wcale.
Czy macie może pomysł czemu tak się dzieje? Znalazłem inny kod
http://tool-man.org/examples/sorting.html
…w którym problem ten nie występuje, ale jest częścią jakiejś sporej skomplikowanej biblioteki i przerobienie go na moje potrzeby chwilowo mnie przerasta, tymczasem kod zamieszczony tutaj jest przejrzysty i miły w obróbce :-)

Pozdrawiam Zych.

Zych
20

Ja też bym chciał sie dowiedzieć jak zrobić ten uchwyt.

MTK
21

Dylev:
Jeśli chcesz po przesuwać i poukładać elementy względem siebie po bokach i w horyzontalnie, wystarczy dodać parametry left i top do DIV’ów, np:

przesuń mnie!
przesuń mnie!

i gotowe

qńqń
22

oj, nie wkleiło znacznika w div dodajesz np left:100; co przesunie element w prawo o 100 pixeli, albo top co analogicznie przesunie element w dół

Dodaj komentarz

Dozwolone tagi: <blockquote>, <code>, <strong>