Hindernisse mit der DataTransfer API beseitigen

Der Nutzer kann Daten auch außerhalb des Browserfensters freigeben.

Vielleicht haben Sie schon von der DataTransfer API gehört, die Teil der HTML5 Drag & Drop API und der Zwischenablagenereignisse ist. Damit lassen sich Daten zwischen Quell- und Empfängerzielen übertragen.

Unterstützte Browser

  • 3
  • 12
  • 3,5
  • 4

Quelle

Drag-Drop- und Kopieren-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 dieselben Interaktionen auch außerhalb des Browserfensters möglich sind.

Sowohl das integrierte Drag-and-drop des Browsers als auch das Kopieren und Einfügen können mit anderen Anwendungen, sowohl im Web als auch auf anderen Plattformen, kommunizieren und sind an keine Quelle gebunden. Die API unterstützt mehrere Dateneinträge mit unterschiedlichem Verhalten, je nachdem, wohin Daten übertragen werden. Ihre Webanwendung kann beim Überwachen eingehender Ereignisse die übertragenen Daten senden und empfangen.

Diese Möglichkeit kann unsere Sicht auf die Freigabe und Interoperabilität in Webanwendungen auf dem Desktop verändern. 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 jeden beliebigen Ort geben.

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

Daten übertragen

Zunächst müssen Sie Drag-drop oder Copy-Paste implementieren. Die folgenden Beispiele zeigen Drag-Drop-Interaktionen, der Vorgang für Kopieren und Einfügen ist jedoch ähnlich. Falls Sie mit der Drag-and-drop API nicht vertraut sind, finden Sie in diesem Artikel eine Erläuterung zu HTML5 Drag-and-drop.

Durch die Bereitstellung von MIME-Typ-codierten Daten können Sie frei mit externen Anwendungen interagieren. Die meisten WYSIWYG-Editoren, Texteditoren und Browser reagieren auf die „einfachen“ 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 die Eigenschaft event.dataTransfer. Dadurch wird eine Instanz von DataTransfer zurückgegeben. 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. Prüfen Sie die empfangenen Ereignisse (drop oder paste) und lesen Sie die Schlüssel. Wenn Sie die Maus über ein Element ziehen, hat der Browser nur Zugriff auf die type-Schlüssel der Daten. Auf die Daten selbst kann erst nach einem Verlust 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 allen Anwendungen weithin unterstützt:

  • text/html:rendert die HTML-Nutzlast in contentEditable-Elementen und WYSIWYG-Editoren wie Google Docs und Microsoft Word.
  • text/plain:: Legt den Wert von Eingabeelementen, den Inhalt von Codeeditoren und das Fallback aus text/html fest.
  • text/uri-list:Ruft die URL auf, wenn Sie die URL in die URL-Leiste oder die Browserseite ziehen. Beim Ablegen eines Verzeichnisses oder des Desktops wird eine URL-Verknüpfung erstellt.

Aufgrund der weitreichenden Akzeptanz von text/html durch WYSIWYG-Editoren ist es sehr nützlich. Wie in HTML-Dokumenten können Sie Ressourcen mithilfe von Daten-URLs oder öffentlich zugänglichen URLs einbetten. Dies funktioniert gut beim Exportieren von Bildern (z. B. aus einem Canvas) in Editoren wie Google Docs.

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

Unten wird gezeigt, wie die DataTransfer API mit Kopieren und Einfügen verwendet wird. 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 einfachen MIME-Typen beschränkt, können aber einen beliebigen Schlüssel verwenden, um die übertragenen Daten zu identifizieren. Dies kann für browserübergreifende Interaktionen innerhalb 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 Internet verbinden

Benutzerdefinierte Formate eignen sich hervorragend für die Kommunikation zwischen Anwendungen, über die Sie die Kontrolle haben. Sie schränken damit auch den Nutzer ein, wenn Daten an Anwendungen übertragen werden, die Ihr Format nicht verwenden. Wenn Sie eine Verbindung zu Drittanbieteranwendungen im gesamten Web herstellen möchten, benötigen Sie ein universelles Datenformat.

Der JSON-LD-Standard (Linked Data) ist hierfür sehr gut geeignet. Er ist schlank und kann in JavaScript problemlos gelesen und geschrieben werden. Schema.org enthält viele vordefinierte Typen, die verwendet werden können, aber auch 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 oder einem Typ verwenden, der Ihrem Anwendungsfall näher kommt, wie Event, Person, MediaObject, Place oder bei Bedarf sogar sehr spezifische Typen wie MedicalEntity. Wenn Sie TypeScript nutzen, können Sie die Schnittstellendefinitionen aus den schema-dts-Typdefinitionen verwenden.

Durch das Senden und Empfangen von JSON-LD-Daten tragen Sie zu einem enger 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 benötigten Informationen sind in den übertragenen Daten enthalten.

Denken Sie an alle Möglichkeiten der Datenübertragung zwischen beliebigen (Web-)Anwendungen ohne Einschränkungen: Sie können Termine aus einem Kalender an Ihre bevorzugte ToDo-App weitergeben, virtuelle Dateien an E-Mails anhängen oder Kontakte teilen. Das wäre toll, oder? Das fängt bei Ihnen an! 🙌

Bedenken

Obwohl die DataTransfer API bereits verfügbar ist, müssen vor der Integration einige Dinge beachtet werden.

Browserkompatibilität

Desktop-Browser unterstützen das oben beschriebene Verfahren alle hervorragend, Mobilgeräte dagegen nicht. Das Verfahren 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 jedoch nicht bestanden. Während Browser sich weiterentwickeln, ist diese Technik derzeit auf Desktop-Browser beschränkt.

Auffindbarkeit

Drag-Drop und Kopier-/Einfügen sind bei der Arbeit an einem Desktop-Computer Interaktionen auf Systemebene, die auf die ersten GUIs vor mehr als 40 Jahren zurückgeführt wurden. Denken Sie daran, wie oft Sie diese Interaktionen zum Organisieren von Dateien genutzt haben. Dies ist im Web noch nicht sehr verbreitet.

Sie müssen die Nutzer über diese neue Interaktion informieren und UX-Muster entwickeln, um dies erkennbar zu machen, insbesondere für Personen, deren Erfahrungen mit Computern bisher auf Mobilgeräte beschränkt waren.

Barrierefreiheit

Drag-Drop ist keine einfache Interaktion, aber die DataTransfer API funktioniert auch mit Kopieren und Einfügen. Achten Sie darauf, dass Sie auf Ereignisse vom Typ „Kopieren“ und „Einfügen“ warten. Es ist mit wenig Aufwand verbunden und Ihre Nutzer werden es Ihnen danken, dass Sie es hinzugefügt haben.

Sicherheit und Datenschutz

Es gibt einige Sicherheits- und Datenschutzaspekte, die Sie bei der Verwendung des Verfahrens beachten sollten.

  • Daten aus der Zwischenablage sind für andere Anwendungen auf dem Gerät des Nutzers verfügbar.
  • Web-Apps, die Sie per Drag-and-drop verschieben, haben Zugriff auf die Eingabetasten, nicht auf die Daten. Die Daten sind erst durch das Einfügen oder Einfügen verfügbar.
  • Die empfangenen Daten sollten wie jede andere Nutzereingabe behandelt, 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 gleicht Browserunterschiede aus, bietet JSON-LD-Dienstprogramme, enthält einen Beobachter zum Reagieren auf Übertragungsereignisse zum Hervorheben von Drop-Bereichen 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 auf Unsplash