Un semplice sistema javascript di Drag and Drop

Recentemente ho sviluppato un semplice sistema javascript di “Drag And Drop” da includere nelle pagine dei miei pannelli di controllo per aumentarne l'usabilità.
Di seguito spiegherò brevemente i prìncipi base di funzionamento dello script e come poterlo utilizzare all'interno delle proprie pagine. A fine pagina trovate uno zip contenente lo script ed una pagina d'esempio.

Esempio Drag and Drop


Recentemente ho sviluppato un semplice sistema javascript di “Drag And Drop” da includere nelle pagine dei miei pannelli di controllo per aumentarne l'usabilità.
Di seguito spiegherò brevemente i prìncipi base di funzionamento dello script e come poterlo utilizzare all'interno delle proprie pagine. A fine pagina trovate uno zip contenente lo script ed una pagina d'esempio.
Ho verificato la compatibilità con Firefox 2, Internet Explorer 7, Internet Explorer 6, Internet Explorer 5.5, Safari 3, Opera 9.

Prìncipi di funzionamento

Vi sono due tipologie di zone, distinguibili dalla classe di stile, che servono come riferimento: la dragZone e la dropZone. La dragZone è l'area dalla quale possono essere prelevati gli oggetti, la dropZone è l'area in cui possono essere rilasciati: le due possono coincidere, o possono essere molteplici.
Viene creato un DIV “mobile”, chiamato drago, al livello più basso del DOM, in modo che le sua posizione non risenta di eventuali contenitori, e viene nascosto. Questo DIV servirà da appoggio per effettuare il movimento dell'elemento selezionato. Il drago contiene quattro HR che servono a disegnarne il bordo lasciandolo vuoto al suo interno, poi vedremo il perché.

Quando viene cliccato un oggetto, lo script verifica che esso si trovi all'interno della dragZone; se sì, allora lo nasconde e assegna al drago, o meglio alle HR in esso contenute, le dimensioni dell'oggetto stesso. Il drago viene visualizzato in corrispondenza del cursore del mouse, con il giusto offset per posizionarlo nella posizione del click: apparirà come un rettangolo vuoto.
Mostrare nella fase di drag l'oggetto stesso creava una serie di complicazioni, dovute al fatto che l'oggetto sotto al mouse sarebbe rimasto sempre quello trascinato e non si sarebbe potuto stabilire il target facilmente, che avrebbero richiesto uno script molto più complesso per essere risolte, e a me piace la semplicità.
Ho detto “quando viene cliccato un oggetto”, ma qual è l'oggetto? Se io clicco un'immagine, l'oggetto cliccato è l'immagine stessa. Ma magari la mia intenzione era quella di spostare tutto il div contenente l'immagine in questione e un paragrafo e un link. Per questo ho introdotto la variabile containerTag che permette di stabilire quale deve essere il tag contenitore cui fare riferimento. Con un po' di pianificazione ed una buona struttura di pagina, si possono ottenere tutti i tipi di contenitori che possono servire.

Dunque, dicevamo che l'oggetto viene trascinato “per finta”, ovvero viene creata l'illusione di trascinamento tramite il drago. Ogni volta che si passa sopra un oggetto presente nella dropZone o nella dragZone, viene eseguita la funzione onDrag, ed ogni volta che l'oggetto viene rilasciato viene eseguita la funzione onDrop.
Tramite la dichiarazione di queste due funzioni si possono far compiere le azioni desiderate ai nostri oggetti trascinati.

Esempio di utilizzo

Nel file che trovate a fondo pagina trovate un esempio semplice di riordino degli elementi LI tramite questo script. Ve lo spiego brevemente:

Prima di tutto bisogna impostare le variabili per adattare lo script al nostro utilizzo:

	<script type="text/javascript">
    var dragClass="DragZone";
    var dropClass="DragZone";
    var containerTag='LI';

Come vedete ho scelto di spostare gli elementi LI e ho dichiarato che la dragZone e la dropZone combaciano: hanno lo stesso nome. Significa che posso rilasciare l'oggetto nella stessa zona in cui l'ho preso.

Ora passo alla dichiarazione delle due funzioni da eseguire quando si passa sopra agli oggetti e quando si rilascia l'oggetto trascinato:

	onDrag=function (drag,target) {
        var container=drag.parentNode.childNodes;
        for(var i=0;container[i];i++) {
            if(container[i]==drag) {
                target.parentNode.insertBefore(drag,target.nextSibling);
                break;
                }
            else if(container[i]==target) {
                target.parentNode.insertBefore(drag,target);
                break;
                }
            }
        }
    onDrop=function (drag,target) {
        document.getElementById('submit').style.display='block';
        }
    </script>

Quando passo sopra gli oggetti, ne effettuo il riordino posizionando l'oggetto dopo o prima del target. Quando rilascio l'oggetto, mostro il tasto “Salva”.

Dulcis in fundo richiamo finalmente lo script:

	<script type="text/javascript" src="drag_and_drop.js"></script>

Essendo uno script giovane e poco testato, potrebbe avere ancora dei difetti. Nel caso ne trovaste, scrivetemi.