Praktyczna lista sortowana metodą przeciągnij i upuść
Budowanie listy, której kolejność można zmieniać za pomocą Drag and Drop API
Praktyczna lista sortowana metodą przeciągnij i upuść to bezpłatna lekcja HTML Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej HTML Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs HTML Academy zawiera 4 lekcji w sumie.
Przegląd wzorca
Aby zbudować listę, w której elementy można przeciągać w celu zmiany kolejności, należy ustawić każdy element jako przeciągalny, zapisać id przeciąganego elementu w dataTransfer podczas dragstart, a podczas upuszczania wstawić przeciągany element przed elementem docelowym lub za nim. DOM i model pozostają zsynchronizowane, jeśli po każdym upuszczeniu kolejność jest odtwarzana na podstawie DOM.
Znaczniki
Należy wyrenderować płaską listę, w której każdy element li ma atrybuty draggable="true" i data-id. Przechowywanie identyfikatorów w elementach sprawia, że procedury obsługi przeciągania nie muszą odpytywać oddzielnego magazynu stanu, aby rozpoznać elementy — źródłem prawdy jest sam element.
<ul id="list">
<li draggable="true" data-id="1">Item 1</li>
<li draggable="true" data-id="2">Item 2</li>
<li draggable="true" data-id="3">Item 3</li>
</ul>dragstart rejestruje źródło
Podczas dragstart należy zapisać id przeciąganego elementu w dataTransfer i dodać klasę "dragging", aby zapewnić wizualną informację zwrotną. effectAllowed="move" informuje przeglądarkę, że chodzi o zmianę kolejności, a nie kopiowanie, dzięki czemu kursor i dropEffect odzwierciedlają operację przenoszenia.
list.addEventListener("dragstart", (e) => {
const li = e.target.closest("li");
if (!li) return;
e.dataTransfer.setData("text/plain", li.dataset.id);
e.dataTransfer.effectAllowed = "move";
li.classList.add("dragging");
});dragover zezwala na upuszczenie
Należy nasłuchiwać zdarzeń na liście (delegowanie zdarzeń), wywołać preventDefault i ustawić dropEffect na "move". Użycie e.target.closest("li") pozwala znaleźć wiersz, nad którym znajduje się kursor, dzięki czemu ta sama procedura obsługi działa dla całej listy.
Obliczanie pozycji wstawienia
Aby zdecydować, czy przeciągany element powinien znaleźć się nad wierszem wskazywanym przez kursor, czy pod nim, należy porównać współrzędną Y kursora z pionowym środkiem wiersza: const before = (e.clientY - rect.top) < rect.height / 2. before=true oznacza wstawienie za pomocą insertBefore, a before=false — za pomocą insertAfter.
function getInsertBefore(target, clientY) {
const rect = target.getBoundingClientRect();
return clientY < rect.top + rect.height / 2;
}drop zmienia kolejność DOM
W procedurze obsługi drop należy wyszukać przeciągany element na podstawie jego id oraz wiersz docelowy znajdujący się pod kursorem. Należy wywołać list.insertBefore(dragged, target) lub list.insertBefore(dragged, target.nextSibling), zależnie od tego, nad którą połową elementu docelowego znajdował się kursor.
dragend usuwa style
Niezależnie od tego, czy upuszczenie się powiodło, czy użytkownik nacisnął klawisz Escape, zdarzenie dragend zawsze jest wywoływane dla źródła. Należy użyć go do usunięcia klasy "dragging" oraz wszelkich wyróżnień miejsc docelowych, aby lista powróciła do stanu bezczynności.
list.addEventListener("dragend", () => {
list.querySelectorAll(".dragging, .over").forEach((el) => {
el.classList.remove("dragging", "over");
});
});Wizualny wskaźnik upuszczenia
Należy wyświetlać cienką linię w miejscu, w którym wyląduje element, używając pseudoelementu CSS dla wskazanego wiersza. Pseudoelement należy przełączać za pomocą klasy "over-top" lub "over-bottom", ustawianej przez procedurę obsługi dragover na podstawie położenia kursora. Użytkownik widzi punkt wstawienia jeszcze przed zwolnieniem przycisku.
Synchronizacja modelu
Po upuszczeniu należy wyznaczyć nową kolejność na podstawie DOM: const order = Array.from(list.children).map((li) => li.dataset.id). Tę tablicę należy wysłać do serwera lub zapisać w stanie — nigdy nie należy utrzymywać równoległego indeksu obok DOM, ponieważ podczas szybkiego przeciągania traci on synchronizację.
Alternatywa z użyciem klawiatury
Należy dodać procedury obsługi klawiszy góra/dół, które przenoszą element mający fokus za pomocą insertBefore. Przeniesienie należy ogłosić za pomocą regionu aria-live ("Item moved up to position 2"). Użytkownicy klawiatury otrzymują tę samą funkcjonalność bez korzystania z przeciągania wizualnego, co ma kluczowe znaczenie dla dostępności.
Rozwiązanie przyjazne ekranom dotykowym
Na urządzeniach mobilnych należy zastąpić natywne przeciąganie zdarzeniami Pointer Events: podczas pointerdown przejąć wiersz, podczas pointermove przesuwać go za pomocą CSS transform, a podczas pointerup wykryć element znajdujący się pod nim i zmienić kolejność. Biblioteki takie jak SortableJS kapsułkują ten wzorzec dla różnych typów danych wejściowych.
Sprawdzenie wiedzy
Dlaczego pozycję wstawienia obliczamy na podstawie położenia kursora względem pionowego środka wskazywanego wiersza?
Podsumowanie
Solidna lista ze zmianą kolejności łączy draggable="true" + dragstart (rejestracja id, effectAllowed=move) + dragover (preventDefault + pozycja wskaźnika) + drop (insertBefore w miejscu wyznaczonym na podstawie środka) + dragend (sprzątanie). Po upuszczeniu zawsze należy wyznaczać nową kolejność na podstawie DOM oraz zapewnić alternatywę z użyciem klawiatury na potrzeby dostępności.
Często zadawane pytania
Czy lekcja „Praktyczna lista sortowana metodą przeciągnij i upuść” jest bezpłatna?
Tak — pełny tekst „Praktyczna lista sortowana metodą przeciągnij i upuść” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu HTML Academy, przejdź na CoddyKit PRO. Kurs HTML Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Praktyczna lista sortowana metodą przeciągnij i upuść”?
Budowanie listy, której kolejność można zmieniać za pomocą Drag and Drop API Ćwiczysz HTML Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć HTML Academy?
Nie wymagamy żadnego doświadczenia. HTML Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Praktyczna lista sortowana metodą przeciągnij i upuść”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji HTML Academy?
Tak. Każda lekcja HTML Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Atrybut draggable i zdarzenie dragstart
- Zdarzenia dragover i drop
- Obiekt dataTransfer
- Praktyczna lista sortowana metodą przeciągnij i upuść