Hindernisse mit der DataTransfer API beseitigen

Der Nutzer kann Daten über das Browserfenster hinaus freigeben.

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.

Unterstützte Browser

  • Chrome: 3.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 4.

Quelle

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. Oft wird jedoch übersehen, dass sich diese Interaktionen auch über das Browserfenster hinaus nutzen lassen.

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 Funktion kann die Art und Weise verändern, wie wir die Freigabe und Interoperabilität in Web-Anwendungen auf dem Computer betrachten. Für die Übertragung von Daten zwischen Anwendungen sind keine eng verbundenen Integrationen mehr erforderlich. Stattdessen können Sie Nutzern die volle Kontrolle darüber geben, wohin sie Daten übertragen möchten.

Ein Beispiel für Interaktionen, die mit der DataTransfer API möglich sind. (Das Video enthält keinen Ton.)

Daten übertragen

Zuerst müssen Sie Drag-and-drop oder Kopieren und Einfügen implementieren. Die folgenden Beispiele zeigen Drag-and-drop-Interaktionen, aber das Kopieren und Einfügen funktioniert ähnlich. Wenn Sie mit der Drag-and-Drop API nicht vertraut sind, finden Sie in diesem Artikel alles Wissenswerte zu HTML5-Drag-and-Drop.

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 „primitiven“ MIME-Typen, die im folgenden Beispiel 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. 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. Der Zugriff auf die Daten selbst ist erst nach der Veröffentlichung möglich.

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:Die HTML-Nutzlast wird in contentEditable-Elementen und in Rich-Text-Editoren (WYSIWYG) wie Google Docs und Microsoft Word gerendert.
  • text/plain:: Legt den Wert von Eingabeelementen, den Inhalt von Code-Editoren und den Fallback von text/html fest.
  • text/uri-list:Ruft die URL auf, wenn sie in die URL-Leiste oder auf die Browserseite abgelegt 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 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 per Kopieren und Einfügen

Unten sehen Sie ein Beispiel für die Verwendung der DataTransfer API mit Interaktionen zum Kopieren und Einfügen. Das Objekt DataTransfer 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 jeden Schlüssel verwenden, um die übertragenen Daten zu identifizieren. Das kann für browserübergreifende Interaktionen innerhalb Ihrer Anwendung nützlich sein. Wie unten gezeigt, können Sie komplexere Daten mit den Funktionen JSON.stringify() und JSON.parse() ü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 zwar hervorragend für die Kommunikation zwischen Anwendungen, die Sie selbst steuern, beschränken aber auch die Nutzer bei der Übertragung von Daten in Anwendungen, 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) eignet sich hervorragend dafür. Es ist effizient und kann in JavaScript einfach gelesen und geschrieben werden. Schema.org enthält viele vordefinierte Typen, die verwendet werden können. Auch benutzerdefinierte Schemadefinitionen sind eine Option.

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 auswählen, der Ihrem Anwendungsfall näher kommt, z. B. Event, Person, MediaObject, Place oder bei Bedarf sogar sehr spezifische 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 umfassende Integrationen mit externen Anwendungen erstellen. Komplizierte API-Integrationen sind nicht erforderlich. Alle erforderlichen Informationen sind in den übertragenen Daten enthalten.

Stellen Sie sich alle Möglichkeiten vor, Daten ohne Einschränkungen zwischen beliebigen (Web-)Anwendungen zu übertragen: Termine aus einem Kalender in Ihrer bevorzugten To-do-App teilen, virtuelle Dateien an E-Mails anhängen, Kontakte teilen. Das wäre toll, oder? Das beginnt bei dir! 🙌

Bedenken

Die DataTransfer API ist zwar bereits verfügbar, aber es gibt einige Dinge, die Sie vor der Integration beachten sollten.

Browserkompatibilität

Desktop-Browser unterstützen die oben beschriebene Methode sehr gut, während dies auf Mobilgeräten nicht der Fall ist. 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. Da sich Browser ständig weiterentwickeln, ist die Funktion derzeit nur 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-and-drop ist nicht sehr barrierefrei, aber die DataTransfer API funktioniert auch mit Kopieren und Einfügen. Achten Sie darauf, dass Sie auf Kopier-/Einfüge-Ereignisse warten. Das ist mit wenig zusätzlichem Aufwand verbunden und Ihre Nutzer werden Ihnen dankbar sein.

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, die Sie per Drag-and-drop verschieben, haben Zugriff auf die Typschlüssel, 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

Möchten Sie die Data Transfer API in Ihrer Anwendung verwenden? Sehen Sie sich die Transmat-Bibliothek auf GitHub an. Diese Open-Source-Bibliothek gleicht Browserunterschiede aus, bietet JSON-LD-Dienstprogramme, enthält einen Beobachter, der auf Übertragungsereignisse reagiert, um Drop-Bereiche hervorzuheben, und ermöglicht die Einbindung der Datenübertragungsvorgänge in vorhandene Drag-and-drop-Implementierungen.

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.