Ermöglicht dem Nutzer, Daten über das Browserfenster hinaus freizugeben.
Vielleicht haben Sie schon von der DataTransfer API gehört, die Teil der HTML5 Drag and Drop API und der Clipboard events ist. Damit lassen sich Daten zwischen Quell- und Empfangszielen übertragen.
Drag-and-drop- und Copy-and-paste-Interaktionen werden häufig für Interaktionen auf einer Seite verwendet, um einfachen Text von A nach B zu übertragen. Was jedoch oft übersehen wird, ist die Möglichkeit, diese Interaktionen auch außerhalb des Browserfensters zu nutzen.
Sowohl die integrierte Drag-and-drop-Funktion des Browsers als auch die Copy-and-Paste-Interaktionen können mit anderen Anwendungen, Webanwendungen oder anderen Anwendungen kommunizieren und sind nicht an einen Ursprung gebunden. Die API unterstützt mehrere Dateneinträge mit unterschiedlichem Verhalten, je nachdem, wohin die Daten übertragen werden. Ihre Webanwendung kann die übertragenen Daten senden und empfangen, wenn sie auf eingehende Ereignisse wartet.
Diese Funktion kann die Art und Weise verändern, wie wir über das Teilen und die Interoperabilität in Webanwendungen auf dem Desktop denken. Für die Übertragung von Daten zwischen Anwendungen sind keine eng gekoppelten Integrationen mehr erforderlich. Stattdessen können Sie Nutzern die volle Kontrolle über die Übertragung von Daten an beliebige Orte geben.
Daten übertragen
Dazu müssen Sie zuerst Drag-and-drop oder Copy-and-paste implementieren. Die folgenden Beispiele zeigen Drag-and-drop-Vorgänge. Das Kopieren und Einfügen funktioniert aber ähnlich. Wenn Sie mit der Drag-and-Drop-API nicht vertraut sind, finden Sie hier einen Artikel, in dem HTML5-Drag-and-Drop erklärt wird.
Wenn Sie Daten mit MIME-Typ bereitstellen, können Sie frei mit externen Anwendungen interagieren. Die meisten WYSIWYG-Editoren, Texteditoren und Browser reagieren auf die „primitiven“ MIME-Typen, die im Beispiel unten verwendet werden.
document.querySelector('#dragSource')
.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'Foo bar');
event.dataTransfer.setData('text/html', '<h1>Foo bar</h1>');
event.dataTransfer.setData('text/uri-list', 'https://example.com');
});
Beachten Sie das Attribut event.dataTransfer. Dies gibt eine Instanz von DataTransfer zurück. Wie Sie sehen, wird dieses Objekt manchmal von Properties mit anderen Namen zurückgegeben.
Der Empfang der Datenübertragung funktioniert fast genauso wie die Bereitstellung. Warten Sie auf die Empfangereignisse (drop oder paste) und lesen Sie die Schlüssel. Wenn Sie ein Element ziehen, hat der Browser nur Zugriff auf die type-Schlüssel der Daten. Auf die Daten selbst kann erst nach einem Drop zugegriffen werden.
document.querySelector('#dropTarget')
.addEventListener('dragover', (event) => {
console.log(event.dataTransfer.types);
// Without this, the drop event won't fire.
event.preventDefault();
});
document.querySelector('#dropTarget')
.addEventListener('drop', (event) => {
// Log all the transferred data items to the console.
for (let type of event.dataTransfer.types) {
console.log({ type, data: event.dataTransfer.getData(type) });
}
event.preventDefault();
});
Drei MIME-Typen werden in vielen Anwendungen unterstützt:
text/html:Rendert die HTML-Nutzlast incontentEditable-Elementen und Rich-Text-Editoren (WYSIWYG) wie Google Docs, Microsoft Word und anderen.text/plain:: Legt den Wert von Eingabeelementen, den Inhalt von Code-Editoren und den Fallback vontext/htmlfest.text/uri-list:Die URL wird aufgerufen, wenn sie in die URL-Leiste oder auf die Browserseite gezogen wird. Wenn Sie ein Element in ein Verzeichnis oder auf den Desktop ziehen, wird eine URL-Verknüpfung erstellt.
Die weitverbreitete Verwendung von text/html durch WYSIWYG-Editoren macht es sehr nützlich. Wie in HTML-Dokumenten können Sie Ressourcen mithilfe von Data-URLs oder öffentlich zugänglichen URLs einbetten. Das funktioniert gut, wenn Sie Visualisierungen (z. B. aus einem Canvas) in Editoren wie Google Docs exportieren.
const redPixel = 'data:image/gif;base64,R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs=';
const html = '<img src="' + redPixel + '" width="100" height="100" alt="" />';
event.dataTransfer.setData('text/html', html);
Übertragen durch Kopieren und Einfügen
Die Verwendung der DataTransfer API mit Copy-and-Paste-Interaktionen wird unten gezeigt. Das DataTransfer-Objekt wird für Zwischenablageereignisse von einer Property namens clipboardData zurückgegeben.
// Listen to copy-paste events on the document.
document.addEventListener('copy', (event) => {
const copySource = document.querySelector('#copySource');
// Only copy when the `activeElement` (i.e., focused element) is,
// or is within, the `copySource` element.
if (copySource.contains(document.activeElement)) {
event.clipboardData.setData('text/plain', 'Foo bar');
event.preventDefault();
}
});
document.addEventListener('paste', (event) => {
const pasteTarget = document.querySelector('#pasteTarget');
if (pasteTarget.contains(document.activeElement)) {
const data = event.clipboardData.getData('text/plain');
console.log(data);
}
});
Benutzerdefinierte Datenformate
Sie sind nicht auf die primitiven MIME-Typen beschränkt, sondern können einen beliebigen Schlüssel verwenden, um die übertragenen Daten zu identifizieren. Das kann für browserübergreifende Interaktionen in Ihrer Anwendung nützlich sein. Wie unten gezeigt, können Sie mit den Funktionen JSON.stringify() und JSON.parse() komplexere Daten übertragen.
document.querySelector('#dragSource')
.addEventListener('dragstart', (event) => {
const data = { foo: 'bar' };
event.dataTransfer.setData('my-custom-type', JSON.stringify(data));
});
document.querySelector('#dropTarget')
.addEventListener('dragover', (event) => {
// Only allow dropping when our custom data is available.
if (event.dataTransfer.types.includes('my-custom-type')) {
event.preventDefault();
}
});
document.querySelector('#dropTarget')
.addEventListener('drop', (event) => {
if (event.dataTransfer.types.includes('my-custom-type')) {
event.preventDefault();
const dataString = event.dataTransfer.getData('my-custom-type');
const data = JSON.parse(dataString);
console.log(data);
}
});
Verbindung zum Web herstellen
Benutzerdefinierte Formate eignen sich zwar hervorragend für die Kommunikation zwischen Anwendungen, die Sie selbst kontrollieren, schränken den Nutzer aber ein, wenn er Daten in Anwendungen übertragen möchte, die Ihr Format nicht verwenden. Wenn Sie eine Verbindung zu Drittanbieteranwendungen im Web herstellen möchten, benötigen Sie ein universelles Datenformat.
Der JSON-LD-Standard (Linked Data) ist dafür sehr gut geeignet. Es ist schlank und lässt sich in JavaScript einfach lesen und schreiben. Schema.org enthält viele vordefinierte Typen, die verwendet werden können. Außerdem sind benutzerdefinierte Schemadefinitionen möglich.
const data = {
'@context': 'https://schema.org',
'@type': 'ImageObject',
contentLocation: 'Venice, Italy',
contentUrl: 'venice.jpg',
datePublished: '2010-08-08',
description: 'I took this picture during our honey moon.',
name: 'Canal in Venice',
};
event.dataTransfer.setData('application/ld+json', JSON.stringify(data));
Wenn Sie die Schema.org-Typen verwenden, können Sie mit dem generischen Typ Thing beginnen oder einen Typ verwenden, der Ihrem Anwendungsfall näher kommt, z. B. Event, Person, MediaObject, Place oder sogar sehr spezifische Typen wie MedicalEntity. Wenn Sie TypeScript verwenden, können Sie die Schnittstellendefinitionen aus den Typdefinitionen von schema-dts verwenden.
Durch das Senden und Empfangen von JSON-LD-Daten tragen Sie zu einem vernetzteren und offeneren Web bei. Wenn Anwendungen dieselbe Sprache sprechen, können Sie umfassende Integrationen mit externen Anwendungen erstellen. Komplizierte API-Integrationen sind nicht erforderlich. Alle benötigten Informationen sind in den übertragenen Daten enthalten.
Stellen Sie sich alle Möglichkeiten vor, Daten ohne Einschränkungen zwischen beliebigen (Web-)Anwendungen zu übertragen: Ereignisse aus einem Kalender in Ihre bevorzugte To-do-App übertragen, virtuelle Dateien an E-Mails anhängen, Kontakte teilen. Das wäre doch toll, oder? Das beginnt bei Ihnen. 🙌
Bedenken
Die DataTransfer API ist zwar schon jetzt verfügbar, aber es gibt einige Dinge, die Sie vor der Integration beachten sollten.
Browserkompatibilität
Desktopbrowser unterstützen die oben beschriebene Technik sehr gut, Mobilgeräte jedoch nicht. Die Technik wurde in allen gängigen Browsern (Chrome, Edge, Firefox, Safari) und Betriebssystemen (Android, ChromeOS, iOS, macOS, Ubuntu Linux und Windows) getestet, aber leider hat sie den Test unter Android und iOS nicht bestanden. Da Browser ständig weiterentwickelt werden, ist die Technik derzeit nur auf Desktopbrowser beschränkt.
Auffindbarkeit
Drag-and-drop und Copy-and-paste sind Interaktionen auf Systemebene, die auf Desktopcomputern verwendet werden und auf die ersten grafischen Benutzeroberflächen vor mehr als 40 Jahren zurückgehen. Überlegen Sie, wie oft Sie diese Interaktionen zum Organisieren von Dateien verwendet haben. Das ist im Web noch nicht sehr verbreitet.
Sie müssen Nutzer über diese neue Interaktion informieren und UX-Muster entwickeln, um sie erkennbar zu machen, insbesondere für Personen, die bisher nur Mobilgeräte verwendet haben.
Bedienungshilfen
Drag-and-drop ist keine sehr zugängliche Interaktion, aber die DataTransfer API funktioniert auch mit Copy-and-Paste. Achten Sie darauf, dass Sie auf Copy-and-Paste-Ereignisse warten. Es ist nicht viel zusätzliche Arbeit erforderlich und Ihre Nutzer werden es Ihnen danken.
Sicherheit und Datenschutz
Bei der Verwendung dieser Technik sind einige Sicherheits- und Datenschutzaspekte zu beachten.
- Die Zwischenablagedaten sind für andere Anwendungen auf dem Gerät des Nutzers verfügbar.
- Webanwendungen, die Sie ziehen, haben Zugriff auf die Typschlüssel, nicht auf die Daten. Die Daten sind erst verfügbar, wenn sie per Drag-and-drop oder per Einfügen übertragen werden.
- Die empfangenen Daten sollten wie jede andere Nutzereingabe behandelt werden. Bereinigen und validieren Sie sie, bevor Sie sie verwenden.
Erste Schritte mit der Transmat-Hilfsbibliothek
Möchten Sie die DataTransfer API in Ihrer Anwendung verwenden? Transmat-Bibliothek auf GitHub Diese Open-Source-Bibliothek gleicht Browserunterschiede aus, bietet JSON-LD-Dienstprogramme, enthält einen Observer, der auf Übertragungsereignisse reagiert, um Drop-Bereiche hervorzuheben, und ermöglicht es Ihnen, die Datenübertragungsvorgänge in bestehende Drag-and-Drop-Implementierungen zu integrieren.
import { Transmat, TransmatObserver, addListeners } from 'transmat';
// Send data on drag/copy.
addListeners(myElement, 'transmit', (event) => {
const transmat = new Transmat(event);
transmat.setData({
'text/plain': 'Foobar',
'application/json': { foo: 'bar' },
});
});
// Receive data on drop/paste.
addListeners(myElement, 'receive', (event) => {
const transmat = new Transmat(event);
if (transmat.hasType('application/json') && transmat.accept()) {
const data = JSON.parse(transmat.getData('application/json'));
}
});
// Observe transfer events and highlight drop areas.
const obs = new TransmatObserver((entries) => {
for (const entry of entries) {
const transmat = new Transmat(entry.event);
if (transmat.hasMimeType('application/json')) {
entry.target.classList.toggle('drag-over', entry.isTarget);
entry.target.classList.toggle('drag-active', entry.isActive);
}
}
});
obs.observe(myElement);
Danksagungen
Hero-Image von Luba Ertel auf Unsplash.