Empfohlene Drag-Typen
Die HTML Drag and Drop API unterstützt das Ziehen verschiedener Datentypen, einschließlich Klartext, URLs, HTML-Code, Dateien usw. Das Dokument beschreibt bewährte Methoden für gängige ziehbare Datentypen.
Ziehen von Text
Zum Ziehen von Text verwenden Sie den Typ text/plain
. Der zweite Datenparameter sollte die gezogene Zeichenkette sein. Zum Beispiel:
event.dataTransfer.setData("text/plain", "This is text to drag");
Das Ziehen von Text in Textfeldern und Auswahlen auf Webseiten wird automatisch vom Browser erledigt, sodass Sie es nicht selbst behandeln müssen.
Es wird empfohlen, immer Daten des Typs text/plain
als Fallback für Anwendungen oder Ziele, die andere Typen nicht unterstützen, hinzuzufügen, es sei denn, es gibt keine logische Textalternative. Fügen Sie diesen Typ text/plain
immer zuletzt hinzu, da er der unspezifischste ist und nicht bevorzugt werden sollte.
Hinweis: In älterem Code können Sie den Typ text/unicode
oder Text
finden. Diese sind gleichbedeutend mit text/plain
und speichern und rufen Klartextdaten ab.
Ziehen von Links
Gezogene Hyperlinks sollten Daten von zwei Typen enthalten: text/uri-list
und text/plain
. Beide Typen sollten die URL des Links für ihre Daten verwenden. Zum Beispiel:
const dt = event.dataTransfer;
dt.setData("text/uri-list", "https://www.mozilla.org");
dt.setData("text/plain", "https://www.mozilla.org");
Wie gewohnt setzen Sie den Typ text/plain
zuletzt als Fallback für den Typ text/uri-list
.
Hinweis: Der URL-Typ ist uri-list
mit einem I, nicht einem L.
Um mehrere Links zu ziehen, trennen Sie jeden Link in den text/uri-list
Daten mit einem CRLF-Zeilenumbruch. Zeilen, die mit einem Nummernzeichen (#
) beginnen, sind Kommentare und sollten nicht als URLs betrachtet werden. Sie können Kommentare verwenden, um den Zweck einer URL, den Titel, der mit einer URL verknüpft ist, oder andere Daten anzugeben.
Warnung: Der text/plain
Fallback für mehrere Links sollte alle URLs, aber keine Kommentare, enthalten.
Zum Beispiel enthält diese Beispiel-text/uri-list
Daten zwei Links und einen Kommentar:
https://www.mozilla.org #A second link http://www.example.com
Wenn Sie einen abgelegten Link abholen, stellen Sie sicher, dass Sie behandeln, wenn mehrere Links gezogen wurden, einschließlich aller Kommentare. Zur Bequemlichkeit kann der spezielle Typ URL
verwendet werden, um auf den ersten gültigen Link innerhalb der Daten für den Typ text/uri-list
zu verweisen.
Warnung: Fügen Sie keine Daten mit dem Typ URL
hinzu – der Versuch, dies zu tun, setzt den Wert des Typs text/uri-list
stattdessen.
const url = event.dataTransfer.getData("URL");
Sie können auch Daten mit dem Mozilla-spezifischen Typ text/x-moz-url
sehen. Wenn es erscheint, sollte es vor dem Typ text/uri-list
erscheinen. Es enthält die URLs der Links gefolgt von ihren Titeln, getrennt durch einen Zeilenumbruch. Zum Beispiel:
https://www.mozilla.org Mozilla http://www.example.com Example
Ziehen von HTML und XML
HTML-Inhalte können den Typ text/html
verwenden. Die Daten für diesen Typ sollten als HTML-Quellcode serialisiert werden. Zum Beispiel wäre es geeignet, seine Daten auf den Wert der innerHTML
Eigenschaft eines Elements zu setzen.
XML-Inhalte können den Typ text/xml
verwenden, aber stellen Sie sicher, dass die Daten wohlgeformtes XML sind.
Sie können auch eine Klartext-Darstellung der HTML- oder XML-Daten mithilfe des Typs text/plain
einbeziehen. Die Daten sollten nur der Text ohne die Quell-Tags oder Attribute sein. Zum Beispiel:
const dt = event.dataTransfer;
dt.setData("text/html", "Hello there, <strong>stranger</strong>");
dt.setData("text/plain", "Hello there, stranger");
Aktualisierungen zu DataTransfer.types
Die neueste Spezifikation diktiert, dass DataTransfer.types
ein eingefrorenes Array von Zeichenketten anstelle einer DOMStringList
zurückgeben sollte (dies wird ab Firefox 52 unterstützt).
Daher funktioniert die Methode contains nicht mehr; die Methode includes sollte stattdessen verwendet werden, um zu überprüfen, ob ein bestimmter Datentyp bereitgestellt wird, mit Code wie dem folgenden:
if ([...event.dataTransfer.types].includes("text/html")) {
// Do something
}
Sie könnten Feature-Erkennung verwenden, um festzustellen, welche Methode auf types
unterstützt wird, und dann den Code entsprechend ausführen.
Ziehen von Bildern
Das direkte Ziehen von Bildern ist nicht üblich. Tatsächlich unterstützt Mozilla das direkte Ziehen von Bildern auf Mac oder Linux nicht. Stattdessen werden Bilder normalerweise nur über ihre URLs gezogen. Um dies zu tun, verwenden Sie den Typ text/uri-list
wie bei anderen URLs. Die Daten sollten die URL des Bildes sein oder eine data:
URL, wenn das Bild nicht auf einer Website oder einem Datenträger gespeichert ist.
Wie bei Links sollten die Daten für den Typ text/plain
auch die URL enthalten. Eine data:
URL ist jedoch normalerweise in einem Textkontext nicht nützlich, sodass Sie die text/plain
Daten in dieser Situation möglicherweise ausschließen möchten.
In Chrome oder anderem privilegierten Code können Sie auch die Typen image/jpeg
, image/png
oder image/gif
verwenden, abhängig vom Bildtyp. Die Daten sollten ein Objekt sein, das die nsIInputStream
Schnittstelle implementiert. Wenn dieser Stream gelesen wird, sollte er die Datenbits für das Bild bereitstellen, als ob das Bild eine Datei dieses Typs wäre.
Sie sollten auch den Typ application/x-moz-file
einbeziehen, wenn sich das Bild auf der Festplatte befindet. Tatsächlich ist dies eine gängige Methode, wie Bilddateien gezogen werden.
Es ist wichtig, die Daten in der richtigen Reihenfolge zu setzen, von den spezifischsten zu den unspezifischeren. Der Standardbildtyp, wie image/jpeg
, sollte zuerst kommen, gefolgt vom application/x-moz-file
Typ. Danach sollten Sie die text/uri-list
Daten setzen und schließlich die text/plain
Daten. Zum Beispiel:
const dt = event.dataTransfer;
dt.setData("text/uri-list", imageURL);
dt.setData("text/plain", imageURL);
Ziehen von Knoten
Knoten und Elemente in einem Dokument können mithilfe des Typs application/x-moz-node
gezogen werden. Die Daten für diesen Typ sollten ein DOM-Knoten sein. Dies ermöglicht es dem Ziel, den tatsächlichen Knoten zu erhalten, von dem das Ziehen gestartet wurde. Beachten Sie, dass Anrufer von einer anderen Domäne nicht auf den Knoten zugreifen können, selbst wenn er fallen gelassen wurde.
Sie sollten immer eine text/plain
Alternative für den Knoten einbeziehen.
Ziehen von benutzerdefinierten Daten
Sie können auch andere Typen verwenden, die Sie für benutzerdefinierte Zwecke erfinden. Streben Sie an, immer eine text/plain
Alternative einzubeziehen, es sei denn, das gezogene Objekt ist spezifisch für eine bestimmte Seite oder Anwendung. In diesem Fall stellt der benutzerdefinierte Typ sicher, dass die Daten nicht anderswo abgelegt werden können.
Dateien in einen Ordner des Betriebssystems ziehen
Möglicherweise möchten Sie eine Datei zu einer vorhandenen Drag-Ereignis-Sitzung hinzufügen und Sie möchten die Datei auch auf die Festplatte schreiben, wenn die Abgabeaktion über einem Ordner im Betriebssystem erfolgt, wenn Ihr Code eine Benachrichtigung über den Speicherort des Zielordners erhält. Dies funktioniert nur in Erweiterungen (oder anderem privilegierten Code), und der Typ application/moz-file-promise
sollte verwendet werden. Das folgende Beispiel bietet einen Überblick über diesen fortgeschrittenen Fall:
// currentEvent is an existing drag operation event
currentEvent.dataTransfer.setData("text/x-moz-url", URL);
currentEvent.dataTransfer.setData("application/x-moz-file-promise-url", URL);
currentEvent.dataTransfer.setData(
"application/x-moz-file-promise-dest-filename",
leafName,
);
function dataProvider() {}
dataProvider.prototype = {
QueryInterface(iid) {
if (
iid.equals(Components.interfaces.nsIFlavorDataProvider) ||
iid.equals(Components.interfaces.nsISupports)
)
return this;
throw Components.results.NS_NOINTERFACE;
},
getFlavorData(aTransferable, aFlavor, aData, aDataLen) {
if (aFlavor === "application/x-moz-file-promise") {
const urlPrimitive = {};
const dataSize = {};
aTransferable.getTransferData(
"application/x-moz-file-promise-url",
urlPrimitive,
dataSize,
);
const url = urlPrimitive.value.QueryInterface(
Components.interfaces.nsISupportsString,
).data;
console.log(`URL file original is = ${url}`);
const namePrimitive = {};
aTransferable.getTransferData(
"application/x-moz-file-promise-dest-filename",
namePrimitive,
dataSize,
);
const name = namePrimitive.value.QueryInterface(
Components.interfaces.nsISupportsString,
).data;
console.log(`target filename is = ${name}`);
const dirPrimitive = {};
aTransferable.getTransferData(
"application/x-moz-file-promise-dir",
dirPrimitive,
dataSize,
);
const dir = dirPrimitive.value.QueryInterface(
Components.interfaces.nsILocalFile,
);
console.log(`target folder is = ${dir.path}`);
const file = Cc["@mozilla.org/file/local;1"].createInstance(
Components.interfaces.nsILocalFile,
);
file.initWithPath(dir.path);
file.appendRelativePath(name);
console.log(`output final path is = ${file.path}`);
// now you can write or copy the file yourself…
}
},
};