In diesem Beitrag werden die Grundlagen von Drag-and-drop erläutert.
Ziehbare Inhalte erstellen
In den meisten Browsern sind Textauswahl, Bilder und Links standardmäßig ziehbar. Wenn Sie beispielsweise einen Link auf einer Webseite ziehen, sehen Sie ein kleines Feld mit einem Titel und URL, die Sie in die Adressleiste oder den Desktop einfügen können, oder navigieren Sie zum Link. Um andere Inhaltstypen ziehbar zu machen, die HTML5 Drag & Drop APIs verwenden.
Wenn Sie ein Objekt ziehbar machen möchten, legen Sie draggable=true
für dieses Element fest. Fast
Alles lässt sich per Drag-and-drop öffnen, darunter Bilder, Dateien, Links, Dateien
-Markup auf Ihrer Seite.
Im folgenden Beispiel wird eine Schnittstelle erstellt, um Spalten neu anzuordnen,
CSS-Raster dargestellt werden. Die grundlegende Auszeichnung für die Spalten sieht folgendermaßen aus, wobei
das Attribut draggable
für jede Spalte, die auf true
gesetzt ist:
<div class="container">
<div draggable="true" class="box">A</div>
<div draggable="true" class="box">B</div>
<div draggable="true" class="box">C</div>
</div>
Hier ist der CSS-Code für die Container- und Box-Elemente. Das einzige Preisvergleichsportal für die
Ziehfunktion ist die cursor: move
Property. Der Rest des Codes steuert das Layout und den Stil des Containers.
und Box-Elementen.
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
}
.box {
border: 3px solid #666;
background-color: #ddd;
border-radius: .5em;
padding: 10px;
cursor: move;
}
Nun können Sie die Elemente ziehen, aber sonst passiert nichts. Hinzufügen müssen Sie die JavaScript API verwenden.
Auf Drag-Events warten
Um den Drag-Prozess zu überwachen, können Sie auf eines der folgenden Ereignisse warten:
Für den Drag-Flow benötigen Sie ein Quellelement, beginnt), die Datennutzlast (das gezogene Objekt) und ein Ziel (ein Bereich, Fallenlassen). Das Quellelement kann fast jedes Element sein. Die Das Ziel ist die Drop-Zone oder die Gruppe von Drop-Zonen, die die Daten akzeptieren, die der Nutzer hat. und versuchen, sie fallen zu lassen. Nicht alle Elemente können Ziele sein. Ihr Ziel darf beispielsweise ein Bild sein.
Ziehfolge starten und beenden
Nachdem Sie die draggable="true"
-Attribute für Ihre Inhalte definiert haben, hängen Sie ein
dragstart
-Event-Handler zum Starten der Ziehsequenz für jede Spalte.
Mit diesem Code wird die Deckkraft der Spalte auf 40% festgelegt, wenn der Nutzer beginnt, sie zu ziehen. und setzen Sie ihn wieder auf 100 %, wenn das Zieh-Ereignis endet.
function handleDragStart(e) {
this.style.opacity = '0.4';
}
function handleDragEnd(e) {
this.style.opacity = '1';
}
let items = document.querySelectorAll('.container .box');
items.forEach(function (item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragend', handleDragEnd);
});
Das Ergebnis ist in der folgenden Glitch-Demo zu sehen. Ziehen Sie ein Element und
die Deckkraft ändert. Da das Quellelement das Ereignis dragstart
enthält, wird die Einstellung
this.style.opacity
auf 40% gibt dem Nutzer visuelles Feedback, dass dieses Element
die aktuell verschobene Auswahl. Wenn Sie das Element ablegen, wird das Quellelement
wird wieder auf 100% Deckkraft zurückgesetzt, obwohl Sie das Drop-Verhalten noch nicht definiert haben.
Zusätzliche visuelle Hinweise hinzufügen
Verwenden Sie die Methode
dragenter
-, dragover
- und dragleave
-Event-Handler. In diesem Beispiel hat der Parameter
Spalten sind nicht nur ziehbar, sondern auch Ablageziele. Helfen Sie dem Nutzer,
indem sie die Rahmenlinie gestrichelt darstellen lassen, wenn sie ein verschobenes Element über ein Element halten.
Spalte. In Ihrem CSS können Sie beispielsweise eine over
-Klasse für
Elemente, die Drop-Ziele sind:
.box.over {
border: 3px dotted #666;
}
Richten Sie dann in Ihrem JavaScript die Event-Handler ein und fügen Sie die over
-Klasse hinzu, wenn
wird die Spalte verschoben. Sie wird entfernt, sobald das gezogene Element geschlossen wird. In
dragend
, entfernen wir auch die Klassen am Ende der
ziehen.
document.addEventListener('DOMContentLoaded', (event) => {
function handleDragStart(e) {
this.style.opacity = '0.4';
}
function handleDragEnd(e) {
this.style.opacity = '1';
items.forEach(function (item) {
item.classList.remove('over');
});
}
function handleDragOver(e) {
e.preventDefault();
return false;
}
function handleDragEnter(e) {
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over');
}
let items = document.querySelectorAll('.container .box');
items.forEach(function(item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
});
In diesem Code sind einige Punkte zu beachten:
Die Standardaktion für das Ereignis
dragover
besteht darin, die EigenschaftdataTransfer.dropEffect
auf"none"
Die EigenschaftdropEffect
wird weiter unten auf dieser Seite behandelt. Fürs Erste Sie sollten nur wissen, dass dasdrop
-Ereignis dadurch nicht ausgelöst wird. Um dies zu überschreiben rufen Siee.preventDefault()
an. Eine weitere gute Praxis ist,false
im selben Handler.Der
dragenter
-Event-Handler wird zum Umschalten derover
-Klasse verwendetdragover
Wenn Siedragover
verwenden, wird das Ereignis wiederholt ausgelöst, während der Nutzer das per Drag-and-drop verschobene Element über eine Spalte enthält, wodurch die CSS-Klasse wiederholt. Dadurch führt der Browser viele unnötige Rendering-Aufgaben durch, was sich auf die User Experience auswirken kann. Wir empfehlen dringend, Wenn Siedragover
verwenden müssen, Drosseln oder Entprellen des Ereignis-Listeners.
Absolviere den Drop
Fügen Sie dem drop
-Ereignis einen Event-Listener hinzu, um das Löschen zu verarbeiten. Im drop
müssen Sie das Standardverhalten des Browsers für Drops,
ist normalerweise eine lästige Weiterleitung. Rufen Sie dazu e.stopPropagation()
auf.
function handleDrop(e) {
e.stopPropagation(); // stops the browser from redirecting.
return false;
}
Achten Sie darauf, den neuen Handler zusammen mit den anderen Handlern zu registrieren:
let items = document.querySelectorAll('.container .box');
items.forEach(function(item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
Wenn Sie den Code zu diesem Zeitpunkt ausführen, wird das Element nicht am neuen Speicherort abgelegt. Bis
Verwenden Sie dazu den DataTransfer
-Objekt enthält.
Die Eigenschaft dataTransfer
enthält die Daten, die bei einer Drag-Aktion gesendet werden. dataTransfer
wird im Ereignis dragstart
festgelegt und im Drop-Ereignis gelesen oder verarbeitet. Anrufen
Mit e.dataTransfer.setData(mimeType, dataPayload)
können Sie das MIME des Objekts festlegen
Typ und Datennutzlast.
In diesem Beispiel lassen wir die Nutzenden die Reihenfolge der Spalten neu anordnen. Dazu müssen Sie zunächst den HTML-Code des Quellelements speichern, Beginn:
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
Im drop
-Ereignis verarbeiten Sie das Löschen der Spalte, indem Sie den Wert der Quellspalte
HTML zum HTML der Zielspalte hinzu, in der Sie die Daten abgelegt haben. Dieses
stellt sicher, dass Nutzende nicht wieder in dieselbe Spalte wechseln,
z. B. von der Seite gezogen wird.
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
}
Das Ergebnis können Sie sich in der folgenden Demo ansehen. Dafür ist eine Desktop-Browser. Die Drag & Drop API wird auf Mobilgeräten nicht unterstützt. Ziehen und lassen Sie die Spalte A über der Spalte B los und achten Sie darauf, wie sich die Positionen ändern:
Weitere Eigenschaften zum Ziehen
Das dataTransfer
-Objekt stellt Eigenschaften bereit, um dem
während des Drag-Vorgangs nutzen und steuern, wie jedes Drop-Ziel auf eine
Datentyp.
dataTransfer.effectAllowed
schränkt die Art des Drag die die Nutzenden mit dem Element ausführen können. Es wird verwendet im Drag-and-drop-Verarbeitungsmodell zum Initialisieren vondropEffect
während die Ereignissedragenter
unddragover
. Die Unterkunft kann die folgende Werte:none
,copy
,copyLink
,copyMove
,link
,linkMove
,move
,all
unduninitialized
.dataTransfer.dropEffect
steuert das Feedback, das der Nutzer während derdragenter
unddragover
erhält. Ereignisse. Wenn der Nutzer den Zeiger über ein Zielelement hält, wird das Objekt Der Cursor zeigt an, welche Art von Vorgang stattfinden wird, z. B. eine Kopie oder einen Zug. Der Effekt kann einen der folgenden Werte annehmen:none
,copy
,link
,move
.e.dataTransfer.setDragImage(imgElement, x, y)
bedeutet, dass statt des standardmäßigen "Ghost Image" des Browsers Feedback geben, ein Ziehsymbol festlegen.
Datei hochladen
In diesem einfachen Beispiel wird eine Spalte sowohl als Drag-Quelle als auch Ziehziel verwendet. Dieses in einer Benutzeroberfläche passieren, in der Nutzende aufgefordert werden, Elemente neu anzuordnen. In einigen Situationen Das Drag-Ziel und die Quelle können unterschiedliche Elementtypen sein, wie in einer Oberfläche bei denen Nutzende ein Bild als Hauptbild für ein Produkt auswählen müssen, das ausgewählte Bild auf ein Ziel zieht.
Drag-and-drop wird häufig verwendet, damit Nutzer Elemente von ihrem Desktop
einer Anwendung. Der Hauptunterschied liegt im drop
-Handler. Anstelle von
dataTransfer.getData()
nicht auf die Dateien zugreifen dürfen. Die Daten befinden sich in der
dataTransfer.files
-Property:
function handleDrop(e) {
e.stopPropagation(); // Stops some browsers from redirecting.
e.preventDefault();
var files = e.dataTransfer.files;
for (var i = 0, f; (f = files[i]); i++) {
// Read the File objects in this FileList.
}
}
Weitere Informationen hierzu finden Sie in Benutzerdefiniertes Drag-and-drop: