So implementieren Sie Drag and Drop in Svelte
Drag and Drop fühlt sich einfach an, bis man versucht, es zu implementieren. Der Browser bietet eine native API, aber diese hat echte Einschränkungen: keine flüssigen Animationen, inkonsistente Touch-Unterstützung und unvorhersehbares Verhalten über verschiedene Browser hinweg. Wenn Sie jemals beobachtet haben, wie Elemente beim Ablegen ungeschickt einrasten, kennen Sie das Problem.
Dieser Leitfaden behandelt zwei praktische Ansätze zur Implementierung von Drag and Drop in Svelte – mit der nativen HTML5-API und mit einer Bibliothek – damit Sie das richtige Werkzeug für das wählen können, was Sie tatsächlich entwickeln.
Wichtigste Erkenntnisse
- Die native HTML5 Drag and Drop API funktioniert für einfaches Neuordnen von Listen ohne Abhängigkeiten, bietet jedoch keine flüssigen Animationen, Touch-Unterstützung oder konsistentes browserübergreifendes Verhalten.
- Svelte 5 Runes (
$state()) und dieondragstart-Attributsyntax vereinfachen reaktives Drag and Drop im Vergleich zu Svelte 3/4. - Für animiertes, mehrlistiges, touch-freundliches oder barrierefreies Drag and Drop ist
svelte-dnd-actioneine praktische Bibliothekswahl. - Drag-Events sind nur clientseitig – in SvelteKit mit SSR sollte Drag-Logik mit
onMountoder einerbrowser-Prüfung abgesichert werden.
Die zwei Ansätze verstehen
Bevor Sie Code schreiben, hilft es zu verstehen, zwischen welchen Optionen Sie wählen.
Native HTML5 Drag and Drop API verwendet browserintegrierte Events: dragstart, dragover, dragenter, dragleave und drop. Sie benötigt keine Abhängigkeiten und funktioniert gut für einfache Anwendungsfälle. Der Kompromiss besteht darin, dass Animationen manuelle Arbeit erfordern, Touch-Unterstützung über verschiedene Geräte hinweg inkonsistent ist und visuelles Feedback während des Ziehens begrenzt ist. Mehr über die API können Sie in der MDN Drag and Drop Dokumentation lesen.
Bibliotheksbasierte Lösungen wie svelte-dnd-action oder Neodrag übernehmen die schwierigen Teile – flüssige FLIP-Animationen, Touch-Unterstützung und barrierefreie Interaktionen – direkt einsatzbereit. Sie erhöhen die Bundle-Größe geringfügig, sparen aber erhebliche Implementierungszeit für alles, was über eine einfache sortierbare Liste hinausgeht.
Drag and Drop in Svelte 5 mit der nativen API implementieren
Hier ist ein sauberes Beispiel für die Neuordnung einer einzelnen Liste mit Svelte 5 Runes-Syntax:
<script>
let items = $state(['Svelte', 'SvelteKit', 'Vite', 'TypeScript']);
let dragIndex = $state(null);
function handleDragStart(event, index) {
dragIndex = index;
event.dataTransfer.effectAllowed = 'move';
}
function handleDragOver(event, index) {
event.preventDefault();
if (dragIndex === null || dragIndex === index) return;
const updated = [...items];
const [moved] = updated.splice(dragIndex, 1);
updated.splice(index, 0, moved);
items = updated;
dragIndex = index;
}
function handleDragEnd() {
dragIndex = null;
}
</script>
<ul>
{#each items as item, index (item)}
<li
draggable="true"
class:dragging={dragIndex === index}
ondragstart={(e) => handleDragStart(e, index)}
ondragover={(e) => handleDragOver(e, index)}
ondragend={handleDragEnd}
>
{item}
</li>
{/each}
</ul>
<style>
li {
padding: 10px 16px;
margin: 6px 0;
background: #f1f1f1;
cursor: grab;
list-style: none;
border-radius: 4px;
}
.dragging {
opacity: 0.4;
}
</style>
Ein paar bemerkenswerte Punkte zu diesem Svelte 5 Pattern:
$state()ersetzt die alten reaktiven Variablendeklarationen aus Svelte 3/4.- Svelte 5 unterstützt auch die
ondragstart-Attributsyntax zusätzlich zur traditionellenon:dragstartEvent-Direktive. - Die Liste aktualisiert sich während des Ziehens (bei
dragover), nicht erst beim Ablegen – dies gibt Benutzern Echtzeit-Feedback.
SvelteKit-Hinweis: Drag-Events sind nur clientseitig. Wenn Sie SvelteKit mit SSR verwenden, umschließen Sie jegliche Drag-bezogene Logik mit onMount oder sichern Sie sie mit einer browser-Prüfung aus $app/environment ab.
Discover how at OpenReplay.com.
Wann svelte-dnd-action stattdessen verwendet werden sollte
Der native Ansatz funktioniert für einfache Szenarien zur Neuordnung von Listen. Sobald Sie jedoch eines der folgenden Dinge benötigen, greifen Sie zu svelte-dnd-action:
- Flüssige FLIP-Animationen zwischen Listenpositionen
- Multi-Listen Drag and Drop (Kanban-Style Boards)
- Touch- und Mobile-Unterstützung ohne zusätzlichen Code
- Barrierefreie Tastaturinteraktionen bereits integriert
Das svelte-dnd-action-Pattern ist unkompliziert – Sie wenden eine use:dndzone-Action auf Ihren Container an, übergeben Ihr Items-Array und behandeln consider- und finalize-Events, um den State zu aktualisieren. Jedes Item benötigt eine eindeutige id-Eigenschaft. Kombinieren Sie es mit Sveltes integrierter flip-Animation und Sie erhalten produktionsreife Drag-Interaktionen in unter 20 Zeilen.
| Anforderung | Verwendung |
|---|---|
| Einfache Listenneuordnung, keine Animationen | Native API |
| Flüssige Animationen, Multi-Listen, Touch | svelte-dnd-action |
| Freies Ziehen von Elementen | Neodrag |
Fazit
Für einfaches Neuordnen von Listen mit Drag and Drop in Svelte bringt Sie die native Browser-API mit Svelte 5 Runes ohne Abhängigkeiten ans Ziel. Für alles Komplexere – animierte Kanban-Boards, Touch-Unterstützung oder barrierefreie Interaktionen – ist svelte-dnd-action die praktische Wahl. Beginnen Sie mit dem nativen Ansatz, um die Mechanik zu verstehen, und wechseln Sie dann zu einer Bibliothek, wenn Ihre Anforderungen dies erfordern.
Häufig gestellte Fragen
Nicht zuverlässig. Die Unterstützung für Drag-Events auf Touch-Geräten ist über mobile Browser hinweg inkonsistent. Um Mobile ordnungsgemäß zu unterstützen, benötigen Sie entweder ein Polyfill wie mobile-drag-drop oder eine Bibliothek wie svelte-dnd-action, die Touch-Interaktionen nativ behandelt.
Ja. svelte-dnd-action funktioniert mit Svelte 5. Sie deklarieren Ihr Items-Array mit $state() und aktualisieren es innerhalb der consider- und finalize-Event-Handler. Die use:dndzone-Direktive bleibt gleich. Stellen Sie nur sicher, dass jedes Item in Ihrem Array eine eindeutige id-Eigenschaft hat, damit die Bibliothek Elemente korrekt verfolgen kann.
Der Browser generiert ein Standard-Geisterbild aus dem Erscheinungsbild des gezogenen Elements. Sie haben mit der nativen API nur begrenzte Kontrolle darüber. Sie können es mit event.dataTransfer.setDragImage() anpassen, um ein benutzerdefiniertes Element oder einen Canvas-Snapshot bereitzustellen, aber für volle visuelle Kontrolle während des Ziehens ist eine Bibliothek wie svelte-dnd-action oder Neodrag besser geeignet.
Multi-Listen Drag and Drop mit der nativen API erfordert das manuelle Tracking von Quell- und Zielcontainern, was schnell komplex wird. svelte-dnd-action vereinfacht dies, indem Sie use:dndzone auf jeden Listencontainer anwenden und denselben Item-Typ über Zonen hinweg teilen können. Items bewegen sich automatisch zwischen Listen, wenn sie über Container gezogen werden.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.