164 votes

Comment fonctionne la fonctionnalité de collage d'image à partir du presse-papiers dans Gmail et Google Chrome 12+?

J'ai remarqué un article de blog de Google qui mentionne la possibilité de coller des images directement depuis le presse-papiers dans un message Gmail si vous utilisez la dernière version de Chrome. J'ai essayé cela avec ma version de Chrome (12.0.742.91 beta-m) et cela fonctionne très bien en utilisant les touches de contrôle 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 réussi à trouver de références à une telle amélioration. Je crois que ZeroClipboard se lie aux événements de frappe pour déclencher sa fonctionnalité flash et, à ce titre, ne fonctionnerait pas via le menu contextuel (en outre, ZeroClipboard est multi-navigateurs et l'article dit que cela fonctionne uniquement avec Chrome).

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

3 votes

Il semble que cela fonctionne de manière aléatoire avec Firefox également. Est-ce que quelqu'un sait si cela est censé être pris en charge avec Firefox ?

262voto

Nick Retallack Points 5994

J'ai passé du temps à expérimenter avec ceci. Il semble en quelque sorte suivre la nouvelle spécification de l'API Clipboard. Vous pouvez définir un gestionnaire d'événements "coller" et regarder event.clipboardData.items, et appeler getAsFile() sur eux pour obtenir un Blob. Une fois que vous avez un Blob, vous pouvez utiliser FileReader pour voir ce qu'il y a dedans. C'est ainsi que vous pouvez obtenir une URL de données pour ce que vous venez de coller dans Chrome :

document.onpaste = function (event) {
    var items = (event.clipboardData || event.originalEvent.clipboardData).items;
    console.log(JSON.stringify(items)); // pourrait vous donner des types MIME
    for (var 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); // URL de données !
            }; 
            reader.readAsDataURL(blob);
        }
    }
};

Une fois que vous avez une URL de données, vous pouvez afficher l'image sur la page. Si vous voulez plutôt la télécharger, vous pourriez utiliser readAsBinaryString, ou vous pourriez la mettre dans un XHR en utilisant FormData.

Édit: Notez que l'élément est de type DataTransferItem. JSON.stringify pourrait ne pas fonctionner sur la liste des éléments, mais vous devriez pouvoir obtenir le type MIME lorsque vous parcourez les éléments.

7 votes

S'accrocher à des pailles ici, mais avez-vous des idées pourquoi event.clipboardData.items semble être 'indéfini' dans Safari 5.1? Ou même comment obtenir le contenu du presse-papiers pour un fichier/blob dans Safari? Fonctionne très bien dans Chrome. On penserait que webkit serait webkit :(

8 votes

@SenicaGonzalez c'est parce que les données n'existent que pendant la durée de l'événement. Après l'événement, elles disparaissent, donc quand vous essayez d'ouvrir l'objet dans l'inspecteur, vous ne verrez rien.

2 votes

Voudriez-vous faire un exemple de soumission d'une requête XMLHttpRequest avec ces données d'image ? Ce serait vraiment sympa :D

66voto

robintibor Points 141

La réponse de Nick semble nécessiter de petits ajustements pour fonctionner toujours :)

// 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 apportés à la réponse de Nick étaient :

var items = event.clipboardData.items;

à

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

Aussi j'ai dû prendre le deuxième élément parmi les éléments collés (le premier semble être text/html si vous copiez une image d'une autre page web dans le presse-papiers). Donc j'ai changé

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

par une boucle trouvant 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 c'est bien ici :$ :)

1 votes

Comment devrions-nous soumettre les données de l'image en tant que XMLHttpRequest?

0 votes

À d'autres lecteurs de ceci, la réponse à cette question peut être incluse là maintenant : stackoverflow.com/questions/18055422/… :)

4 votes

Je ne comprends pas. Quand je colle des fichiers dans le navigateur, le clipboardData.items est toujours vide dans Google Chrome (Firefox fonctionne). Chrome a maintenant besoin presque autant d'optimisation qu'IE utilisait autrefois.

24voto

Daniel X Moore Points 6026

Voici un plugin jQuery fluide enveloppant tout l'accord (essentiellement les mêmes principes que la réponse de Nick): http://strd6.com/2011/09/html5-javascript-pasting-image-data-in-chrome/

Il a une démo en direct, un code source annoté, et tout.

7voto

Rich Apodaca Points 7327

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

Code Snippet — Accéder aux images du presse-papiers avec JavaScript

et ceci:

Le désert du collage (ou, pourquoi l'événement onPaste est un désordre)

Le premier lien décrit une façon d'obtenir des images du presse-papiers en n'utilisant que du JavaScript sur Firefox et Chrome. Le deuxième lien contient un post-scriptum mentionnant que la même technique a été adaptée à IE (version inconnue).

1voto

saurshaz Points 175

Autant que je sache -

Avec les fonctionnalités d'HTML 5 (File Api et les fonctionnalités associées) - l'accès aux données des images du presse-papiers est désormais possible avec du javascript simple.

Cependant, cela ne fonctionne pas sur IE (tout ce qui est inférieur à IE 10). Je ne sais pas non plus beaucoup sur le support d'IE 10.

Pour IE, les options que je crois être les options de "fallback" sont : soit en utilisant l'API Adobe AIR soit en utilisant une applet signée

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X