Surmonter les obstacles avec l'API DataTransfer

Autorisez l'utilisateur à partager des données au-delà de la fenêtre du navigateur.

Vous avez peut-être entendu parler L'API DataTransfer, qui est une partie du API HTML5 glisser-déposer et Événements du presse-papiers. Il peut pour transférer des données entre les cibles sources et destinataires.

Navigateurs pris en charge

  • Chrome: 3. <ph type="x-smartling-placeholder">
  • Edge: 12 <ph type="x-smartling-placeholder">
  • Firefox: 3.5. <ph type="x-smartling-placeholder">
  • Safari: 4. <ph type="x-smartling-placeholder">

Source

Les interactions de type "glisser-déposer" et "copier-coller" sont souvent utilisées pour des interactions au sein d'une page. pour transférer un texte simple de A à B. Mais ce qui est souvent négligé, c'est la capacité à utiliser ces mêmes interactions au-delà de la fenêtre du navigateur.

Les interactions de type glisser-déposer intégrées au navigateur et copier-coller peuvent communiquer avec d'autres applications, Web ou autres, et ne sont associées à aucune origine. L'API accepte plusieurs les entrées de données avec des comportements différents selon l’endroit vers lequel les données sont transférées. Votre application Web peut envoyer et recevoir les données transférées lors de l'écoute d'événements entrants.

Cette fonctionnalité peut changer notre façon de penser le partage et l'interopérabilité dans le Web sur des ordinateurs de bureau. Le transfert de données d'une application à une autre des intégrations fortement couplées. À la place, vous pouvez donner aux utilisateurs le contrôle total les données où qu'ils le souhaitent.

<ph type="x-smartling-placeholder">
</ph>
Exemple d'interactions possibles avec l'API DataTransfer. (La vidéo n'inclut pas de son.)

Transfert des données

Pour commencer, vous devez implémenter le glisser-déposer ou le copier-coller. Exemples ci-dessous montrent les interactions de type glisser-déposer, mais le processus de copier-coller est similaire. Si vous ne connaissez pas l'API de glisser-déposer, vous trouverez un excellent article la fonctionnalité de glisser-déposer HTML5, qui explique tout ce qu'il faut savoir sur la fonctionnalité de glisser-déposer HTML5.

En fournissant des données à clé de type MIME, vous pouvez interagir librement avec des applications externes. La plupart des éditeurs WYSIWYG, des éditeurs de texte et des navigateurs répondent au message « primitif » types MIME utilisés dans la fonction dans l'exemple ci-dessous.

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');
});

Notez la propriété event.dataTransfer. Cela renvoie une instance de DataTransfer En tant que vous verrez, cet objet est parfois renvoyé par des propriétés ayant d'autres noms.

Recevoir le transfert de données fonctionne presque de la même manière que le fournir. Écouter les événements de réception (drop ou paste) et lire les clés. Lorsque vous faites glisser un élément, le navigateur n'a accès aux clés type des données. Les données elles-mêmes ne sont accessibles qu'après une dépôt.

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();
});

Trois types MIME sont largement acceptés dans les applications:

  • text/html:affiche la charge utile HTML dans des éléments contentEditable et des éléments enrichis. des éditeurs de texte (WYSIWYG) comme Google Docs, Microsoft Word, etc.
  • text/plain: Définit la valeur des éléments d'entrée, du contenu des éditeurs de code et de la création de remplacement. à partir de text/html.
  • text/uri-list:permet d'accéder à l'URL lorsque l'utilisateur le place dans la barre d'adresse ou sur la page du navigateur. Une URL sera créé lors du dépôt sur un répertoire ou sur le bureau.

L'adoption généralisée de text/html par les éditeurs WYSIWYG le rend très utile. Comme en HTML documents, vous pouvez intégrer des ressources en utilisant URL de données ou publiquement les URL accessibles. Cela fonctionne bien avec l'exportation d'éléments visuels (par exemple, d'un canevas) vers des éditeurs tels que 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);

Transférer à l'aide d'un copier-coller

L'utilisation de l'API DataTransfer avec des interactions de copier-coller est illustrée ci-dessous. Notez que L'objet DataTransfer est renvoyé par une propriété appelée clipboardData pour les événements du presse-papiers.

// 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);
  }
});

Formats de données personnalisés

Vous n'êtes pas limité aux types MIME primitifs, mais vous pouvez utiliser n'importe quelle clé pour identifier les éléments transférés. données. Cela peut être utile pour les interactions entre navigateurs au sein de votre application. Comme indiqué ci-dessous, vous peuvent transférer des données plus complexes à l'aide des fonctions JSON.stringify() et JSON.parse().

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);
  }
});

Se connecter au Web

Bien que les formats personnalisés soient parfaits pour la communication entre les applications que vous contrôlez, limite également l'utilisateur lors du transfert de données vers des applications qui n'utilisent pas votre format. Si vous souhaitez vous connecter à des applications tierces sur le Web, vous avez besoin d'un format de données universel.

La norme JSON-LD (données associées) est un excellent candidat pour cela. Il est légère et facile à lire et à écrire en JavaScript. Schema.org contient de nombreuses vous pouvez aussi utiliser des types prédéfinis et des définitions de schémas personnalisées.

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));

Lorsque vous utilisez des types schema.org, vous pouvez commencer par le type générique Thing, ou utilisez des éléments plus proches de votre cas d'utilisation, comme Event, Person, MediaObject, Place ou même des types très spécifiques tels que MedicalEntity si nécessaire. Lorsque vous utilisez TypeScript, vous pouvez utiliser le d'interface à partir des définitions de type schema-dts.

En transmettant et en recevant des données JSON-LD, vous contribuez à un Web plus connecté et ouvert. Avec applications parlant le même langage, vous pouvez créer des intégrations avancées avec des applications. Il n'est pas nécessaire d'intégrer des API compliquées. toutes les informations nécessaires incluses dans les données transférées.

Pensez à toutes les possibilités qui s'offrent à vous pour transférer des données des restrictions: partage d'événements d'un agenda avec votre application ToDo préférée, ajout de fichiers virtuels à e-mails, partage de contacts. Ce serait super, non ? C'est à vous de jouer ! 🙌

Problèmes

Bien que l'API DataTransfer soit disponible dès aujourd'hui, vous devez prendre connaissance de certains points avant de procéder à l'intégration.

Compatibilité du navigateur

Les navigateurs pour ordinateur sont tous compatibles avec la technique décrite ci-dessus, contrairement aux appareils mobiles. non. Cette technique a été testée sur les principaux navigateurs (Chrome, Edge, Firefox, Safari) et (Android, ChromeOS, iOS, macOS, Ubuntu Linux et Windows), mais malheureusement, Android et iOS a échoué au test. Bien que les navigateurs continuent de se développer, cette technique est limitée pour le moment. sur les navigateurs pour ordinateur uniquement.

Visibilité

Le glisser-déposer et le copier-coller sont des interactions au niveau du système lorsque vous travaillez sur un ordinateur de bureau, avec remontent aux premières interfaces graphiques il y a plus de 40 ans. Réfléchissez au nombre de fois que vous avez utilisé ces interactions pour organiser les fichiers. Ce n'est pas encore très courant sur le Web.

Vous devrez informer les utilisateurs de cette nouvelle interaction et trouver des modèles d'UX pour que cette reconnaissables, en particulier pour les personnes qui n’ont jusqu’à présent pas utilisé d’appareils mobiles.

Accessibilité

Le glisser-déposer n'est pas une interaction très accessible, mais l'API DataTransfer fonctionne également avec le copier-coller. Veillez à écouter les événements copier-coller. Cela ne demande pas beaucoup de travail supplémentaire et vos utilisateurs vous serez reconnaissant de l'avoir ajouté.

Sécurité et confidentialité

Lorsque vous utilisez cette technique, vous devez tenir compte de certains points relatifs à la sécurité et à la confidentialité.

  • Les données du presse-papiers sont disponibles pour d'autres applications sur l'appareil de l'utilisateur.
  • Les applications Web que vous faites glisser ont accès aux touches de type, mais pas aux données. Les données uniquement est disponible par glisser-déposer.
  • Les données reçues doivent être traitées comme toute autre entrée utilisateur. de nettoyer et de valider avant de les utiliser.

Premiers pas avec la bibliothèque d'aide Transmat

Êtes-vous intéressé par l'utilisation de l'API DataTransfer dans votre application ? Consultez les Bibliothèque Transmat sur GitHub. Cette bibliothèque open source aligne les navigateurs différences, fournit des utilitaires JSON-LD, contient un observateur pour répondre aux événements de transfert pour en mettant en évidence les zones de dépôt et en vous permettant d'intégrer les opérations de transfert de données dans les opérations de glisser-déposer existantes mises en œuvre.

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);

Remerciements

Image héros de Luba Ertel sur Unsplash.