Cum să utilizați API-ul HTML Drag and Drop

Funcția de tragere și plasare reprezintă o componentă fundamentală ce îmbunătățește considerabil interacțiunea utilizatorului, facilitând o navigare fluidă și intuitivă. Fie că dezvoltați un instrument de încărcare a fișierelor, o listă ordonabilă sau un joc interactiv, cunoașterea modalităților de utilizare eficientă a acestui API este o competență esențială pentru orice dezvoltator web.

Bazele funcționalității de tragere și plasare în HTML

Un sistem tipic de tragere și plasare implică două tipuri de elemente: elementele sursă, care pot fi mutate de utilizator prin intermediul mouse-ului, și elementele destinație, care definesc zonele unde elementele pot fi plasate.

Pentru a activa funcționalitatea de tragere și plasare, trebuie să specificați browserului care elemente pot fi mutate. Un element devine trasabil atunci când are atributul HTML `draggable` setat la `true`, după cum urmează:

 <div draggable="true">Acest element poate fi tras</div>

În momentul în care utilizatorul inițiază acțiunea de tragere, browserul generează o imagine „fantomă” implicită, oferind feedback vizual asupra elementului mutat.

Această imagine implicită poate fi personalizată. Pentru a face acest lucru, selectați elementul trasabil din DOM, creați o nouă imagine și adăugați un ascultător de eveniment `dragstart`:

 let imagine = new Image();
imagine.src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Twemoji_1f600.svg/220px-Twemoji_1f600.svg.png";

document.querySelector('div').addEventListener('dragstart', (event)=>{
event.dataTransfer.setDragImage(imagine, 10, 10);
})

Metoda `setDragImage` primește trei parametri: imaginea personalizată, decalajul orizontal și decalajul vertical al acesteia. La rularea codului, se va observa că imaginea implicită de tragere a fost înlocuită cu cea personalizată.

Pentru a permite o zonă de plasare, trebuie să preveniți comportamentul implicit prin anularea evenimentelor `dragenter` și `dragover`:

 const zonaDePlasare = document.querySelector("drop-target");

zonaDePlasare.addEventListener("dragenter", (ev) => {
ev.preventDefault();
});

zonaDePlasare.addEventListener("dragover", (ev) => {
ev.preventDefault();
});

Înțelegerea interfeței DragEvent

JavaScript oferă o interfață `DragEvent` care reprezintă o interacțiune de tip tragere și plasare inițiată de utilizator. Mai jos este o listă a tipurilor posibile de evenimente gestionate de interfața `DragEvent`:

  • `drag`: Acest eveniment este declanșat continuu în timpul procesului de tragere a unui element.
  • `dragend`: Se declanșează când operațiunea de tragere se finalizează, fie prin eliberarea butonului mouse-ului, fie prin anulare (tasta escape).
  • `dragenter`: Se declanșează când un element tras intră într-o zonă validă de plasare.
  • `dragleave`: Se declanșează când un element tras părăsește o zonă de plasare.
  • `dragover`: Se declanșează în mod repetat în timp ce un element tras este menținut deasupra unei zone de plasare.
  • `dragstart`: Se declanșează la începutul unei operațiuni de tragere.
  • `drop`: Se declanșează când un element tras este plasat într-o zonă de plasare.

Atunci când un fișier este tras în browser dintr-un mediu extern (ex: managerul de fișiere al sistemului de operare), browserul nu va declanșa evenimentele `dragstart` sau `dragend`.

Interfața `DragEvent` este utilă pentru a trimite evenimente personalizate de tragere programatic. De exemplu, pentru a face ca un element `div` să declanșeze evenimente de tragere la încărcarea paginii, urmați acești pași: Mai întâi, creați un eveniment personalizat `DragEvent()`:

 const evenimentCustomDragStart = new DragEvent('dragstart', {
dataTransfer: new DataTransfer(),
})

const evenimentCustomDragEnd = new DragEvent('dragend');

În codul de mai sus, `evenimentCustomDragStart` este o instanță a lui `DragEvent()`. Primul argument al constructorului reprezintă tipul evenimentului, iar al doilea este un obiect care conține cheia `dataTransfer`, reprezentând o instanță a obiectului `DataTransfer`. Apoi, selectați elementul din DOM de unde doriți să pornească evenimentul:

 const elementTrasabil = document.querySelector("#draggable");

Adăugați ascultătorii de eveniment:

 elementTrasabil.addEventListener('dragstart', (event) => {
console.log('Tragerea a început!');
event.dataTransfer.setData('text/plain', 'Salut, lume!');
});

elementTrasabil.addEventListener('dragend', () => {
console.log('Tragerea s-a încheiat!');
});

În primul ascultător, se afișează mesajul „Tragerea a început!”, iar metoda `setData` este invocată pentru a stoca date în proprietatea `dataTransfer` a obiectului eveniment. Acum, puteți declanșa evenimentele personalizate:

 elementTrasabil.dispatchEvent(evenimentCustomDragStart);
elementTrasabil.dispatchEvent(evenimentCustomDragEnd);

Transferul de date cu DataTransfer

Obiectul `dataTransfer` servește ca o punte de legătură între elementul sursă (cel care poate fi tras) și elementul țintă (zona unde se poate plasa) în timpul operațiunii de tragere și plasare. Acesta acționează ca un container temporar pentru datele pe care doriți să le partajați între aceste elemente.

Aceste date pot fi sub diverse forme, cum ar fi text, adrese URL sau tipuri de date personalizate, ceea ce îl face un instrument versatil pentru implementarea unei game variate de funcționalități de drag-and-drop.

Utilizarea metodei setData() pentru a împacheta datele

Pentru a transfera date dintr-un element trasabil către un element de destinație, se utilizează metoda `setData()`, oferită de obiectul `dataTransfer`. Această metodă permite împachetarea datelor și specificarea tipului acestora. Iată un exemplu de bază:

 element.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'Salut, lume!');
});

Când utilizatorul începe să tragă elementul specificat, `setData()` împachetează textul „Salut, lume!” cu tipul de date `text/plain`. Aceste date devin asociate cu evenimentul de tragere și pot fi accesate de către zona de plasare în timpul operațiunii.

Preluarea datelor cu metoda getData()

În ascultătorul de eveniment al elementului de destinație, datele transferate pot fi preluate utilizând metoda `getData()`:

 element.addEventListener('drop', (event) => {
const dateTransferate = event.dataTransfer.getData('text/plain');
console.log(`Date primite: ${dateTransferate}`);
});

Codul de mai sus preia datele de tipul `text/plain`, același tip setat anterior cu metoda `setData()`. Astfel, datele transferate pot fi accesate și manipulate în contextul zonei de plasare.

Cazuri de utilizare pentru interfețele drag and drop

Integrarea funcționalității de drag-and-drop în aplicațiile web poate oferi o îmbunătățire semnificativă, dar este esențial să înțelegeți când și de ce ar trebui să o implementați.

  • Încărcătoare de fișiere: Permiterea utilizatorilor să tragă fișiere direct din desktop sau managerul de fișiere într-o zonă de plasare desemnată simplifică procesul de încărcare.
  • Liste sortabile: Dacă aplicația dvs. implică liste de elemente, cum ar fi liste de sarcini, liste de redare sau galerii de imagini, utilizatorii ar putea aprecia posibilitatea de a reordona elementele prin tragere și plasare.
  • Tablouri de bord interactive: Pentru instrumentele de vizualizare și raportare a datelor, drag-and-drop poate oferi o modalitate intuitivă de personalizare a tablourilor de bord, prin rearanjarea widget-urilor și diagramelor.

Aspecte legate de accesibilitate

Deși drag-and-drop este o caracteristică atractivă și îmbunătățește experiența utilizatorului, este esențial ca implementarea să fie accesibilă tuturor utilizatorilor, inclusiv celor cu dizabilități. Furnizați metode alternative de interacțiune, cum ar fi comenzile de la tastatură, pentru a face aplicația cât mai incluzivă.