web-dev-qa-db-fra.com

Comment fonctionne la fonctionnalité coller une image à partir du presse-papiers dans Gmail et Google Chrome 12+?)

J'ai remarqué un message de Google qui mentionne la possibilité de coller des images directement du Presse-papiers dans un message Gmail si vous utilisez la dernière version de Chrome. J'ai essayé ceci avec ma version de Chrome (12.0.742.91 beta-m) et cela fonctionne très bien avec les touches de commande ou le menu contextuel.

À partir de ce comportement, je dois supposer que la dernière version de webkit utilisée dans Chrome est capable de gérer les images dans l'événement de collage Javascript, mais je n'ai pas pu localiser de référence à une telle amélioration. Je crois que ZeroClipboard se lie aux événements de pression de touche pour déclencher sa fonctionnalité flash et ne fonctionnerait donc pas dans le menu contextuel (également, ZeroClipboard est compatible avec plusieurs navigateurs et l'article indique que cela ne fonctionne qu'avec Chrome).

Alors, comment cela fonctionne-t-il et où l'amélioration a été apportée à Webkit (ou Chrome) qui active cette fonctionnalité?

138
Emil Lerch

J'ai passé du temps à expérimenter avec cela. Il semble suivre en quelque sorte le nouveau spécification API du presse-papier . Vous pouvez définir un gestionnaire d'événements "coller" et consulter event.clipboardData.items, puis appeler getAsFile () pour obtenir un blob. Une fois que vous avez un blob, vous pouvez utiliser FileReader dessus pour voir ce qu’il contient. Voici comment obtenir une URL de données pour les éléments que vous venez de coller dans 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);
    }
  }
}

Une fois que vous avez une URL de données, vous pouvez afficher l'image sur la page. Si vous souhaitez le télécharger à la place, vous pouvez utiliser readAsBinaryString ou le placer dans un fichier XHR à l'aide de FormData .

210
Nick Retallack

La réponse de Nick semble avoir besoin de petits changements pour continuer à fonctionner :)

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

Exemple de code en cours d'exécution: http://jsfiddle.net/bt7BU/225/

Donc, les changements dans la réponse aux pseudos étaient:

var items = event.clipboardData.items;

à

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

De plus, je devais prendre le deuxième élément des éléments collés (le premier semble être text/html si vous copiez une image d’une autre page Web dans le tampon). Alors j'ai changé

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

à une boucle recherchant l'élément contenant l'image (voir ci-dessus)

Je ne savais pas comment répondre directement à la réponse de Nick, j'espère que tout va bien ici: $ :)

48
robintibor

Voici un plugin jQuery qui résume toute la transaction (essentiellement les mêmes principes que réponse de Nick ): http://strd6.com/2011/09/html5-javascript-pasting-image -data-in-chrome /

Il contient une démonstration en direct, un code source annoté et tout le reste.

24
Daniel X Moore

Les navigateurs Web continuent d'avancer. J'ai récemment trouvé ceci:

Extrait de code - Accès aux images du presse-papiers avec Javascript

et ça:

The Waste de Paste (ou pourquoi l'événement onPaste est un désordre)

Le premier lien décrit un moyen d'obtenir des images du Presse-papiers en utilisant JavaScript uniquement sur Firefox et Chrome. Le deuxième lien contient un post-scriptum qui mentionne que la même technique a été adaptée à IE (version inconnue).

7
Rich Apodaca

Pour autant que je sache -

Avec les fonctionnalités HTML 5 (File Api et les fonctions associées), il est désormais possible d’accéder aux images du presse-papiers en javascript simple.

Toutefois, cela ne fonctionne pas sur IE (rien inférieur à IE 10)). Je ne connais pas grand chose au sujet du support IE10 également.

Pour IE, les optiens que je crois être les options de "repli" utilisent soit l’API AIR d’Adobe ou un applet signé

2
saurshaz

Wow, c'est cool. Je n'ai pas encore plongé dans le code source de gmail pour le découvrir (je l'ai fait avec la fonctionnalité de glissement), mais j'imagine qu'il s'agit d'une extension de l'API glisser/déposer qui chrome = a déjà été étendu. Il existe une description décente du fonctionnement de la fonctionnalité de glisser-déposer sur le bureau: http://www.thecssninja.com/javascript/gmail-dragout qui peut au moins vous indiquer dans la bonne direction.

1
Mark Kahn

Cela provient d'un exemple avec angular2 TypeScript qui fonctionne pour mon projet. J'espère que ça aide quelqu'un. La logique est la même pour les autres cas.

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

Voici une implémentation en direct:

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

0
Sandeep K Nair