Abbattere le barriere con l'API DataTransfer

Consente all'utente di condividere i dati oltre la finestra del browser.

Forse hai sentito parlare API DataTransfer, ovvero parte del API di trascinamento HTML5 ed eventi degli appunti. Può essere utilizzato per trasferire i dati tra la destinazione di origine e quella di destinazione.

Supporto dei browser

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

Origine

Le interazioni di trascinamento e copia-incolla vengono spesso utilizzate per le interazioni all'interno di una pagina per trasferire un testo semplice da A a B. Ma ciò che spesso viene trascurato è la possibilità di usare queste stesse interazioni per andare oltre la finestra del browser.

Sia le interazioni di trascinamento e copia-incolla del browser possono comunicare con altre applicazioni, sul web o di altro tipo, e non sono legati ad alcuna origine. L'API supporta più le voci di dati con comportamenti diversi in base a dove vengono trasferiti i dati. Il tuo l'applicazione web può inviare e ricevere i dati trasferiti durante l'ascolto di eventi in arrivo.

Questa funzionalità può cambiare il nostro modo di pensare alla condivisione e all'interoperabilità sul web applicazioni su computer. Il trasferimento di dati tra applicazioni non richiede l'utilizzo più strettamente collegate. Puoi invece dare agli utenti il controllo completo sul trasferimento dove vogliono.

Un esempio di interazioni possibili con l'API DataTransfer. (Il video non include l'audio).

Trasferimento di dati

Per iniziare, dovrai implementare il trascinamento o il copia e incolla. Gli esempi di seguito mostrano le interazioni con il trascinamento, ma il processo per il copia e incolla è simile. Se non conosci l'API di trascinamento, c'è un ottimo articolo spiegando il trascinamento HTML5, che spiega i dettagli.

Se fornisci dati con chiave di tipo MIME, puoi interagire liberamente con applicazioni esterne. La maggior parte degli editor, degli editor di testo e dei browser WYSIWYG risponde al concetto di "primitivo" tipi MIME utilizzati nel di esempio qui sotto.

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

Osserva la proprietà event.dataTransfer. Viene restituita un'istanza di DataTransfer Come che a volte viene restituito da proprietà con altri nomi.

La ricezione del trasferimento di dati funziona quasi come l'invio. Ascolta gli eventi in ricezione (drop o paste) e leggi le chiavi. Quando trascini un elemento, il browser ha accesso solo alle chiavi type dei dati. I dati stessi sono accessibili solo dopo un rilascio.

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

Esistono tre tipi MIME ampiamente supportati nelle varie applicazioni:

  • text/html: visualizza il payload HTML in elementi contentEditable e rich media editor di testo (WYSIWYG), come Documenti Google, Microsoft Word e altri.
  • text/plain: Imposta il valore degli elementi di input, dei contenuti degli editor di codice e del video di riserva da text/html.
  • text/uri-list: consente di accedere all'URL quando si apre la barra dell'URL o la pagina del browser. Un URL verrà creata quando si rilascia su una directory o sul desktop.

L'adozione diffusa di text/html da parte degli editor WYSIWYG lo rende molto utile. Come in HTML documenti, puoi incorporare le risorse URL di dati o pubblicamente URL accessibili. Questa opzione è particolarmente utile per esportare immagini (ad esempio da un canvas) a editor come Documenti Google.

const redPixel = 'data:image/gif;base64,R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs=';
const html = '<img src="' + redPixel + '" width="100" height="100" alt="" />';
event.dataTransfer.setData('text/html', html);

Trasferisci utilizzando copia e incolla

Di seguito è mostrato l'utilizzo dell'API DataTransfer con interazioni di copia-incolla. Nota che l'oggetto DataTransfer viene restituito da una proprietà denominata clipboardData per gli eventi Appunti.

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

Formati di dati personalizzati

Non sei limitato ai tipi MIME primitivi, ma puoi utilizzare qualsiasi chiave per identificare i tipi MIME trasferiti e i dati di Google Cloud. Questo può essere utile per le interazioni tra browser all'interno della tua applicazione. Come mostrato di seguito, può trasferire dati più complessi usando le funzioni JSON.stringify() e 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);
  }
});

Connessione del web in corso...

Sebbene i formati personalizzati siano ottimi per la comunicazione tra le applicazioni che hai sotto il tuo controllo, limita anche il trasferimento dei dati verso applicazioni che non utilizzano il tuo formato. Se vuoi connettersi ad applicazioni di terze parti sul web, è necessario un formato di dati universale.

A questo scopo, lo standard JSON-LD (Linked Data) è un ottimo candidato. È leggero e facile da leggere e scrivere in JavaScript. Schema.org contiene molte è possibile utilizzare tipi predefiniti e le definizioni di schemi personalizzati.

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

Quando utilizzi i tipi di schema.org, puoi iniziare con il tipo generico Thing, o usare qualcosa di più simile al tuo caso d'uso, come Event, Person, MediaObject, luogo o anche tipi molto specifici come MedicalEntity, se necessario. Quando utilizzi TypeScript, puoi utilizzare lo delle definizioni dell'interfaccia dalle definizioni del tipo schema-dts.

Trasmettendo e ricevendo i dati JSON-LD, supporterai un web più connesso e aperto. Con applicazioni che parlano la stessa lingua, è possibile creare profonde integrazioni con diverse applicazioni. Non sono necessarie integrazioni complicate dell'API; tutte le informazioni necessarie inclusi nei dati trasferiti.

Pensa a tutte le possibilità di trasferire dati tra qualsiasi applicazione (web) senza restrizioni: condivisione di eventi da un calendario all'app Attività preferita, aggiunta di file virtuali a le email, condividere i contatti. Sarebbe fantastico, vero? Inizia da te. 🙌

Problemi

Sebbene l'API DataTransfer sia disponibile già da oggi, ci sono alcuni aspetti da tenere presenti prima dell'integrazione.

Compatibilità del browser

I browser desktop supportano tutti la tecnica descritta sopra, mentre i dispositivi mobili sì . La tecnica è stata testata su tutti i principali browser (Chrome, Edge, Firefox, Safari) e sistemi operativi (Android, ChromeOS, iOS, macOS, Ubuntu Linux e Windows), ma purtroppo Android e iOS non ha superato il test. Mentre i browser continuano a svilupparsi, per ora la tecnica è limitata solo ai browser desktop.

Visibilità

Il trascinamento e il copia-incolla sono interazioni a livello di sistema quando si lavora su un computer desktop, con che affonda le radici nelle prime GUI più di 40 anni fa. Pensa a quante volte hai ha usato queste interazioni per organizzare i file. Questo non è ancora molto comune sul web.

Dovrai informare gli utenti in merito a questa nuova interazione e proporre modelli UX per noti, soprattutto per le persone la cui esperienza finora con i computer è limitata ai dispositivi mobili.

Accessibilità

Il trascinamento non è un'interazione molto accessibile, ma l'API DataTransfer funziona anche con il copia e incolla. Assicurati di ascoltare gli eventi di copia e incolla. Non richiede molto lavoro e i tuoi utenti ti saremo grati di averla aggiunta.

Sicurezza e privacy

Ci sono alcune considerazioni sulla sicurezza e sulla privacy di cui è necessario essere a conoscenza quando si utilizza questa tecnica.

  • I dati degli appunti sono disponibili per altre applicazioni sul dispositivo dell'utente.
  • Le applicazioni web che stai trascinando hanno accesso ai tasti di digitazione, non ai dati. Solo i dati diventa disponibile tramite rilascio o incolla.
  • I dati ricevuti devono essere trattati come qualsiasi altro input utente. disinfetta e convalida prima dell'uso.

Introduzione alla libreria di supporto Transmat

Vuoi utilizzare l'API DataTransfer nella tua applicazione? Ti consigliamo di dare un'occhiata Libreria Transmat su GitHub. Questa libreria open source allinea il browser le differenze, fornisce utilità JSON-LD, contiene un osservatore per rispondere agli eventi di trasferimento evidenziando le aree interessate e consente di integrare le operazioni di trasferimento dei dati tra quelle di trascinamento esistenti implementazioni.

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

Ringraziamenti

Immagine hero di Luba Ertel su Rimuovi schermo.