Come funziona l'immagine incolla dalla funzionalità degli Appunti in Gmail e Google Chrome 12+?


148

Ho notato un post sul blog di Google che menziona la possibilità di incollare le immagini direttamente dagli Appunti in un messaggio Gmail se si utilizza l'ultima versione di Chrome. Ho provato questo con la mia versione di Chrome (12.0.742.91 beta-m) e funziona benissimo usando i tasti di controllo o il menu contestuale.

Da quel comportamento devo supporre che l'ultima versione del webkit utilizzata in Chrome sia in grado di gestire le immagini nell'evento di incollaggio Javascript, ma non sono stato in grado di individuare alcun riferimento a tale miglioramento. Credo che ZeroClipboard si leghi agli eventi keypress per attivare la sua funzionalità flash e come tale non funzionerebbe attraverso il menu di scelta rapida (inoltre, ZeroClipboard è cross-browser e il post dice che funziona solo con Chrome).

Quindi, come funziona e dove è stato apportato il miglioramento a Webkit (o Chrome) che abilita la funzionalità?


3
Sembra che funzioni in modo casuale anche con Firefox. Qualcuno sa se questo dovrebbe essere supportato con Firefox?
Sébastien,

Risposte:


231

Ho trascorso un po 'di tempo a sperimentare questo. Sembra seguire le nuove specifiche dell'API degli Appunti . È possibile definire un gestore eventi "incolla" e guardare event.clipboardData.items e chiamare getAsFile () su di essi per ottenere un BLOB. Una volta che hai un BLOB , puoi usare FileReader su di esso per vedere cosa c'è dentro. Ecco come puoi ottenere un url di dati per le cose che hai appena incollato in Chrome:

// window.addEventListener('paste', ... or
document.onpaste = function(event){
  var items = (event.clipboardData || event.originalEvent.clipboardData).items;
  console.log(JSON.stringify(items)); // will give you the mime types
  for (index in items) {
    var item = items[index];
    if (item.kind === 'file') {
      var blob = item.getAsFile();
      var reader = new FileReader();
      reader.onload = function(event){
        console.log(event.target.result)}; // data url!
      reader.readAsDataURL(blob);
    }
  }
}

Una volta che hai un url di dati puoi visualizzare l'immagine sulla pagina. Se invece vuoi caricarlo, puoi usare readAsBinaryString o metterlo in un XHR usando FormData .


6
Stringendo a botte qui, ma qualche idea sul perché event.clipboardData.items sembra essere "indefinito" in Safari 5.1? O anche come ottenere il contenuto degli appunti per un file / BLOB in Safari? Funziona alla grande con Chrome. Penseresti che il webkit sarebbe webkit :(
Gavin Gilmour il

7
@SenicaGonzalez questo perché i dati esistono solo per la durata dell'evento. Dopo l'evento, non c'è più, quindi quando provi a aprire l'oggetto nell'ispettore non vedrai nulla.
Nick Retallack,

3
lo eseguo su Firefox e var blob = items [0] .getAsFile () lancio TypeError: gli articoli non sono definiti
chinna_82

2
Ti dispiacerebbe fare un esempio su come inviare un XMLHttpRequest con tali dati immagine? Sarebbe davvero bello: D
poitroae

1
Ecco come puoi inviarlo utilizzando XMLHttpRequest, l'ho scritto in un blog dopo averlo implementato: blog.securevideo.com/2013/11/27/…
JT Taylor

56

La risposta di Nick sembra aver bisogno di piccole modifiche per funzionare ancora :)

// window.addEventListener('paste', ... or
document.onpaste = function (event) {
  // use event.originalEvent.clipboard for newer chrome versions
  var items = (event.clipboardData  || event.originalEvent.clipboardData).items;
  console.log(JSON.stringify(items)); // will give you the mime types
  // find pasted image among pasted items
  var blob = null;
  for (var i = 0; i < items.length; i++) {
    if (items[i].type.indexOf("image") === 0) {
      blob = items[i].getAsFile();
    }
  }
  // load image if there is a pasted image
  if (blob !== null) {
    var reader = new FileReader();
    reader.onload = function(event) {
      console.log(event.target.result); // data url!
    };
    reader.readAsDataURL(blob);
  }
}

Esempio di codice in esecuzione: http://jsfiddle.net/bt7BU/225/

Quindi le modifiche alla risposta dei nick sono state:

var items = event.clipboardData.items;

per

var items = (event.clipboardData  || event.originalEvent.clipboardData).items;

Inoltre ho dovuto prendere il secondo elemento dagli elementi incollati (il primo sembra essere text / html se copi un'immagine da un'altra pagina web nel buffer). Quindi sono cambiato

  var blob = items[0].getAsFile();

in un ciclo che trova l'elemento che contiene l'immagine (vedi sopra)

Non sapevo come rispondere direttamente alla risposta di Nick, spero che vada bene qui: $ :)


1
Come dovremmo inviare i dati dell'immagine come XMLHttpRequest?
poitroae,

Per gli altri la lettura di questo, la risposta a questa domanda può essere inclusa lì adesso: stackoverflow.com/questions/18055422/... :)
robintibor

4
Non capisco. Quando incollo i file nel browser, clipboardData.itemsè sempre vuoto in Google Chrome (Firefox funziona). Il Chrome ora ha bisogno di quasi la stessa ottimizzazione di prima di IE.
Tomáš Zato - Ripristina Monica il

1
Piccola modifica: if (blob! = Null) {(o imposta blob = null
nell'inizializzazione

1
event.clipboardData.itemsha funzionato bene per me sull'ultimo Chrome, non sei sicuro di quando event.originalEvent...sarà utile?
Ruben Martinez Jr.,


5

I browser Web continuano ad avanzare. Recentemente ho trovato questo:

Snippet di codice - Accesso alle immagini degli Appunti con Javascript

e questo:

The Paste Wasteland (o, perché l'evento onPaste è un casino)

Il primo link descrive un modo per ottenere immagini degli appunti usando JavaScript solo su Firefox e Chrome. Il secondo link contiene un poscritto che menziona la stessa tecnica adattata a IE (versione sconosciuta).


Firefox non attiva nemmeno Modifica | Incolla la voce di menu per me, quindi non vedo affatto come funziona in Firefox.
podperson

Entrambi questi link non funzionano al momento del commento.
Crazywako,

2

Per quanto ne so -

Con le funzionalità HTML 5 (File Api e relativi), ora è possibile accedere ai dati delle immagini degli Appunti con javascript semplice.

Questo tuttavia non funziona su IE (niente meno di IE 10). Non so molto del supporto anche per IE10.

Per IE, le opzioni che ritengo siano le opzioni di "fallback" utilizzano o l'API AIR di Adobe o un'applet firmata


1

Wow, è fantastico. Non mi sono ancora tuffato nella fonte di Gmail per capirlo (l'ho fatto con la funzionalità di trascinamento), ma suppongo che sia un'estensione dell'API di trascinamento della selezione che Chrome ha già esteso. C'è un discreto resoconto su come funziona la funzionalità di trascinamento sul desktop: http://www.thecssninja.com/javascript/gmail-dragout che può almeno indirizzarti nella giusta direzione.


0

Questo è un esempio con dattiloscritto angular2 che funziona per il mio progetto. Spero che aiuti qualcuno. La logica è uguale anche per altri casi.

https://gist.github.com/sandeepsuvit/a8ba77faebba260455985504be24aef7

Ecco un'implementazione live:

https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.ts


1
Potresti spiegare quale processo hai seguito? È possibile aprire il collegamento https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.tsin Chrome e quindi fare clic con il pulsante destro del mouse su un'immagine da qualsiasi sito Web. Quindi incollalo nella casella di testo fornita. Dovrebbe funzionare in questo modo.
Sandeep K Nair

copiato da opere di immagini web. Ho provato le immagini da Windows Explorer, ecco perché allora non funzionava. Ti capita di conoscere un modo per gestire l'immagine copiata da Windows Explorer per incollarla sulla pagina Web ?.
Battle Hawk,

Non ho ancora provato questa opzione. Spero che tu possa ottenere approfondimenti da queste librerie https://github.com/layerssss/paste.js/, invece https://github.com/JoelBesada/pasteboard. Ci sono demo disponibili su questi link che puoi provare.
Sandeep K Nair,

event.clipboardData è vuoto quando ho incollato l'immagine sulle macchine del sistema operativo Windows. Qualcuno può spiegare perché questo accade?
Tunç Doğan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.