Mechanizm „przeciągnij i upuść” stanowi kluczową funkcję, która podnosi poziom interakcji użytkownika ze stroną internetową oraz zapewnia płynność obsługi. Niezależnie od tego, czy projektujesz narzędzie do transferu plików, listę z opcją zmiany kolejności, czy też interaktywną grę, umiejętność efektywnego wykorzystania możliwości tego API jest niezwykle istotna w zestawie narzędzi każdego twórcy stron internetowych.
Podstawowe zasady działania „przeciągnij i upuść” w HTML
Typowy schemat operacji „przeciągnij i upuść” obejmuje dwa rodzaje elementów. Pierwszy to obiekty, które użytkownik może przesuwać za pomocą kursora, natomiast drugi typ to elementy docelowe, określające miejsca, w których użytkownik może upuścić przesuwany obiekt.
Aby wdrożyć funkcję przeciągania i upuszczania, konieczne jest zdefiniowanie w kodzie, które elementy mają być przesuwane. W tym celu, element musi zawierać atrybut HTML, który zezwala na przeciąganie. Atrybut ten powinien mieć wartość ustawioną na „true”, zgodnie z poniższym przykładem:
<div draggable="true">Ten element można przeciągać</div>
W momencie rozpoczęcia operacji przeciągania, przeglądarka wyświetla standardowy obraz „ducha”, który zazwyczaj informuje o przeciąganym elemencie.
Istnieje możliwość dostosowania tego obrazu i zastąpienia go własnym. W tym celu należy wybrać element przeciągany z modelu DOM, utworzyć nowy obraz reprezentujący niestandardowy „duch” oraz dodać detektor zdarzenia „dragstart”, tak jak w poniższym przykładzie:
let img = new Image();
img.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(img, 10, 10);
})
W zaprezentowanym fragmencie kodu metoda „setDragImage” przyjmuje trzy parametry. Pierwszy z nich wskazuje na obraz. Dwa kolejne określają przesunięcie obrazu w poziomie i pionie. Po uruchomieniu tego kodu w przeglądarce i próbie przeciągnięcia elementu, widoczny będzie nowy, niestandardowy obraz zamiast domyślnego „ducha”.
Aby umożliwić upuszczanie elementów, należy zapobiec domyślnemu zachowaniu przeglądarki poprzez anulowanie zdarzeń „dragenter” oraz „dragover”, jak pokazano poniżej:
const dropElement = document.querySelector("drop-target");dropElement.addEventListener("dragenter", (ev) => {
ev.preventDefault();
});dropElement.addEventListener("dragover", (ev) => {
ev.preventDefault();
});
Zrozumienie interfejsu DragEvent
JavaScript posiada interfejs o nazwie „DragEvent”, który reprezentuje interakcję użytkownika związaną z funkcją „przeciągnij i upuść”. Poniżej znajduje się lista możliwych typów zdarzeń w ramach tego interfejsu:
- „drag”: Zdarzenie wywoływane w trakcie przesuwania elementu przez użytkownika.
- „dragend”: Zdarzenie aktywowane po zakończeniu operacji przeciągania lub w momencie jej przerwania przez użytkownika (np. zwolnienie przycisku myszy lub naciśnięcie klawisza Escape).
- „dragenter”: Zdarzenie wywoływane, gdy przeciągany element wejdzie w obszar potencjalnego miejsca upuszczenia.
- „dragleave”: Zdarzenie wywoływane, gdy element przeciągany opuszcza obszar potencjalnego miejsca upuszczenia.
- „dragover”: Zdarzenie wywoływane podczas przesuwania przeciąganego elementu nad obszarem docelowym.
- „dragstart”: Zdarzenie aktywowane na początku procesu przeciągania.
- „drop”: Zdarzenie wywoływane w momencie upuszczenia elementu przez użytkownika na obszarze docelowym.
W sytuacji, gdy użytkownik przeciąga plik do okna przeglądarki z zewnątrz (np. z menedżera plików), przeglądarka nie wywoła zdarzeń „dragstart” ani „dragend”.
Interfejs „DragEvent” może być przydatny w przypadku, gdy chcesz programowo wywołać niestandardowe zdarzenie przeciągania. Na przykład, jeśli zależy Ci, aby element div wywoływał niestandardowe zdarzenia przeciągania zaraz po załadowaniu strony, możesz to zrealizować w następujący sposób. Najpierw utwórz nowy, niestandardowy obiekt „DragEvent()”:
const customDragStartEvent = new DragEvent('dragstart', {
dataTransfer: new DataTransfer(),
})const customDragEndEvent = new DragEvent('dragend');
W powyższym kodzie, „customDragStartEvent” jest instancją obiektu „DragEvent()”. Konstruktor tego obiektu przyjmuje dwa argumenty. Pierwszy z nich określa rodzaj zdarzenia przeciągania, które może być jednym z siedmiu wcześniej wymienionych typów zdarzeń.
Drugi argument to obiekt z kluczem „dataTransfer”, który reprezentuje instancję obiektu „DataTransfer”. Szczegóły jego działania zostaną omówione w dalszej części artykułu. Następnie, należy pobrać z modelu DOM element, dla którego chcemy wywołać zdarzenie:
const draggableElement = document.querySelector("#draggable");
Kolejnym krokiem jest dodanie słuchaczy zdarzeń w następujący sposób:
draggableElement.addEventListener('dragstart', (event) => {
console.log('Przeciąganie rozpoczęte!');
event.dataTransfer.setData('text/plain', 'Witaj, świecie!');
});draggableElement.addEventListener('dragend', () => {
console.log('Przeciąganie zakończone!');
});
W pierwszym słuchaczu zdarzeń funkcja wywołania zwrotnego rejestruje komunikat „Przeciąganie rozpoczęte!” i aktywuje metodę „setData” na właściwości „dataTransfer” obiektu zdarzenia. W tym momencie można wyzwalać niestandardowe zdarzenia, takie jak:
draggableElement.dispatchEvent(customDragStartEvent);
draggableElement.dispatchEvent(customDragEndEvent);
Przekazywanie danych za pomocą DataTransfer
Obiekt „dataTransfer” pełni rolę łącznika pomiędzy elementem źródłowym (elementem, który można przeciągać) a elementem docelowym (obszarem, na którym można upuścić element). Jest to tymczasowy kontener, w którym przechowywane są dane przesyłane pomiędzy tymi elementami podczas operacji przeciągania i upuszczania.
Dane te mogą mieć różną formę, np. tekst, adresy URL czy też niestandardowe typy danych. To czyni obiekt „dataTransfer” uniwersalnym narzędziem, które znajduje zastosowanie w wielu implementacjach „przeciągnij i upuść”.
Użycie metody „setData()” do pakowania danych
Aby przesłać dane z elementu przeciąganego do elementu docelowego, należy użyć metody „setData()”, która jest udostępniana przez obiekt „dataTransfer”. Metoda ta umożliwia umieszczenie danych, które mają być przekazane, i określenie ich typu. Przykładowy kod:
element.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'Witaj, świecie!');
});
W momencie rozpoczęcia przeciągania, metoda „setData()” umieszcza tekst „Witaj, świecie!” wraz z typem danych „text/plain” w obiekcie „dataTransfer”. Dane te są powiązane ze zdarzeniem przeciągania, a element docelowy może uzyskać do nich dostęp podczas operacji upuszczania.
Pobieranie danych za pomocą metody „getData()”
Po stronie odbierającej, w słuchaczu zdarzeń elementu docelowego, można pobrać przesłane dane za pomocą metody „getData()”:
element.addEventListener('drop', (event) => {
const transferredData = event.dataTransfer.getData('text/plain');
console.log(`Otrzymane dane: ${transferredData}`);
});
Powyższy fragment kodu pobiera dane o tym samym typie („text/plain”), który został wcześniej ustawiony za pomocą metody „setData()”. W ten sposób, można uzyskać dostęp do przesłanych danych i modyfikować je w kontekście elementu docelowego.
Zastosowania interfejsów „przeciągnij i upuść”
Włączenie funkcji „przeciągnij i upuść” do aplikacji internetowych może znacząco poprawić wygodę użytkowania. Ważne jest jednak, aby zrozumieć, kiedy i dlaczego należy stosować to rozwiązanie.
- Przesyłanie plików: umożliwienie użytkownikom przeciągania plików bezpośrednio z pulpitu lub menedżera plików do wyznaczonego obszaru upuszczania, znacząco upraszcza proces przesyłania.
- Listy z opcją sortowania: jeśli aplikacja prezentuje listy elementów, takie jak lista zadań, lista odtwarzania czy galeria obrazów, użytkownicy mogą docenić możliwość zmiany ich kolejności za pomocą „przeciągnij i upuść”.
- Interaktywne pulpity nawigacyjne: w narzędziach do wizualizacji danych i raportowania, „przeciągnij i upuść” może być skutecznym sposobem na dostosowywanie układu pulpitów nawigacyjnych poprzez zmianę położenia widżetów i wykresów.
Dostępność interfejsów „przeciągnij i upuść”
Choć funkcja „przeciągnij i upuść” jest atrakcyjna wizualnie i podnosi komfort użytkowania, niezwykle istotne jest zadbanie o dostępność jej implementacji dla wszystkich użytkowników, w tym osób z niepełnosprawnościami. Należy zapewnić alternatywne metody interakcji, takie jak sterowanie klawiaturą, aby aplikacja była wszechstronna.