Dem Nutzer ermöglichen, Daten über das Browserfenster hinaus freizugeben.
Möglicherweise haben Sie schon von der DataTransfer API gehört, die Teil der HTML5 Drag-and-drop API und der Zwischenablageereignisse ist. Sie kann zum Übertragen von Daten zwischen Quell- und Empfängerzielen verwendet werden.
Die Drag-and-drop- und die Kopier-und-Einfügen-Interaktionen werden häufig für Interaktionen innerhalb einer Seite verwendet, um einfachen Text von A nach B zu übertragen. Häufig wird jedoch übersehen, dass dieselben Interaktionen auch über das Browserfenster hinaus genutzt werden können.
Sowohl die integrierte Drag-and-drop-Funktion als auch die Kopier-/Einfüge-Interaktionen des Browsers können mit anderen Anwendungen, Web- oder anderen, 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 eingehende Ereignisse überwacht.
Diese Möglichkeit kann die Art und Weise verändern, wie wir die Freigabe und Interoperabilität in Webanwendungen auf Desktop-Computern betrachten. Für die Übertragung von Daten zwischen Anwendungen sind keine eng verbundenen Integrationen mehr erforderlich. Stattdessen können Sie den Nutzern die volle Kontrolle über die Übertragung von Daten an einen beliebigen Ort geben.
Daten übertragen
Zunächst müssen Sie Drag-drop oder Copy-Paste implementieren. Die folgenden Beispiele zeigen Drag-and-drop-Interaktionen, aber das Kopieren und Einfügen funktioniert ähnlich. Wenn Sie nicht mit der Drag-and-drop API vertraut sind, finden Sie im Artikel Drag-and-drop zu HTML5 den hilfreichen Artikel zur Erläuterung der Besonderheiten von HTML5.
Wenn Sie Daten mit einem MIME-Typ angeben, können Sie frei mit externen Anwendungen interagieren. Die meisten WYSIWYG-Editoren, Texteditoren und Browser reagieren auf die im folgenden Beispiel verwendeten "primitiven" MIME-Typen.
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
. Dadurch wird eine Instanz von DataTransfer
zurückgegeben. Wie Sie sehen, wird dieses Objekt manchmal von Eigenschaften mit anderen Namen zurückgegeben.
Der Empfang der Datenübertragung funktioniert fast genauso wie die Bereitstellung. Hören Sie auf die Empfangsereignisse (drop
oder paste
) und lesen Sie die Schlüssel. Beim Ziehen über ein Element hat der Browser nur Zugriff auf die type
-Schlüssel der Daten. Auf die Daten selbst kann erst nach dem Löschen 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/html
fest.text/uri-list
:Die URL wird aufgerufen, wenn sie auf die URL-Leiste oder die Browserseite verschoben wird. Wenn Sie die URL auf ein Verzeichnis oder den Desktop ziehen, wird ein URL-Verknüpfung erstellt.
Da text/html
in WYSIWYG-Editoren weit verbreitet ist, ist es sehr nützlich. Wie in HTML-Dokumenten können Sie Ressourcen mithilfe von Daten-URLs oder öffentlich zugänglichen URLs einbetten. Das funktioniert gut, wenn Sie Bilder (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);
Durch Kopieren und Einfügen übertragen
Im Folgenden wird die Verwendung der DataTransfer API mit Interaktionen vom Typ „Kopieren und Einfügen“ dargestellt. Das Objekt DataTransfer
wird von einer Eigenschaft namens clipboardData
für Ereignisse in der Zwischenablage 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 jeden 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);
}
});
Das Web verbinden
Benutzerdefinierte Formate eignen sich hervorragend für die Kommunikation zwischen Anwendungen, die Sie selbst steuern. Sie schränken jedoch auch den Nutzer ein, wenn Daten an Anwendungen übertragen werden, die nicht Ihr Format verwenden. Wenn Sie eine Verbindung zu Drittanbieteranwendungen im Web herstellen möchten, benötigen Sie ein universelles Datenformat.
Der Standard JSON-LD ist dafür gut geeignet. Es ist kompakt und leicht in JavaScript zu lesen und zu schreiben. Schema.org enthält viele vordefinierte Typen, die verwendet werden können, sowie benutzerdefinierte Schemadefinitionen.
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 etwas verwenden, das eher Ihrem Anwendungsfall entspricht, z. B. Event, Person, MediaObject, Place oder sogar hochspezifische Typen wie MedicalEntity. Wenn Sie TypeScript verwenden, können Sie die Schnittstellendefinitionen aus den schema-dts-Typdefinitionen verwenden.
Wenn Sie JSON-LD-Daten senden und empfangen, tragen Sie zu einem vernetzten und offenen Web bei. Wenn Anwendungen dieselbe Sprache sprechen, können Sie tiefe Integrationen mit externen Anwendungen erstellen. Komplizierte API-Integrationen sind nicht erforderlich. Alle erforderlichen Informationen sind in den übertragenen Daten enthalten.
Denken Sie an alle Möglichkeiten der Datenübertragung zwischen beliebigen (Webanwendungen) ohne Einschränkungen: Termine aus einem Kalender für Ihre bevorzugte ToDo-App freigeben, virtuelle Dateien an E-Mails anhängen, Kontakte freigeben. Das wäre toll, oder? Das beginnt bei dir! 🙌
Bedenken
Die DataTransfer API ist zwar heute verfügbar, es gibt jedoch einige Dinge, die Sie vor der Integration beachten sollten.
Browserkompatibilität
Desktop-Browser bieten alle eine hervorragende Unterstützung für die oben beschriebene Technik, Mobilgeräte dagegen nicht. Die Methode wurde in allen gängigen Browsern (Chrome, Edge, Firefox, Safari) und Betriebssystemen (Android, ChromeOS, iOS, macOS, Ubuntu Linux und Windows) getestet. Leider haben Android und iOS den Test nicht bestanden. Browser werden zwar weiterentwickelt, doch derzeit ist diese Methode auf Desktop-Browser beschränkt.
Auffindbarkeit
Drag-and-drop und Kopieren und Einfügen sind Interaktionen auf Systemebene, die bei der Arbeit auf einem Computer verwendet werden. Sie gehen auf die ersten GUIs vor mehr als 40 Jahren zurück. Überlegen Sie, wie oft Sie diese Interaktionen zum Organisieren von Dateien verwendet haben. Das ist im Web noch nicht sehr verbreitet.
Sie müssen die Nutzer über diese neue Interaktion informieren und UX-Muster entwickeln, um sie erkennbar zu machen, insbesondere für Nutzer, die bisher nur Erfahrung mit Mobilgeräten haben.
Bedienungshilfen
Drag-Drop ist keine sehr zugängliche Interaktion, aber die DataTransfer API funktioniert auch mit Kopieren und Einfügen. Achten Sie darauf, dass Sie auf Kopier-/Einfüge-Ereignisse warten. Es erfordert keinen zusätzlichen Aufwand und Ihre Nutzer werden es Ihnen danken, dass Sie es hinzugefügt haben.
Sicherheit und Datenschutz
Bei der Verwendung dieser Methode sind einige Sicherheits- und Datenschutzaspekte zu beachten.
- Zwischenablagedaten sind für andere Anwendungen auf dem Gerät des Nutzers verfügbar.
- Webanwendungen, über die Sie ziehen, haben Zugriff auf die Typtasten, nicht auf die Daten. Die Daten sind erst nach dem Ziehen oder Einfügen verfügbar.
- Die empfangenen Daten sollten wie jede andere Nutzereingabe behandelt werden. Sie müssen vor der Verwendung bereinigt und validiert werden.
Erste Schritte mit der Transmat-Hilfsbibliothek
Freuen Sie sich darauf, die DataTransfer API in Ihrer Anwendung zu verwenden? Werfen Sie einen Blick auf die Transmat-Bibliothek auf GitHub. Diese Open-Source-Bibliothek ordnet Browserunterschiede an, bietet JSON-LD-Dienstprogramme, enthält einen Beobachter, 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 bei Unsplash.