Hindernisse mit der DataTransfer API beseitigen

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.

Browser Support

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

Source

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.

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

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 in contentEditable-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 von text/html fest.
  • 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'