2010-12-09 40 views
12

Avec la nouvelle API de fichier en Javascript, vous pouvez lire des fichiers en Javascript pour créer des URLs de données pour afficher des photos de clientide côté client. Je me demande si vous pouvez atteindre l'objet File dans le rappel onload du FileReader. Je vais illustrer cela par un exemple:API de fichiers HTML5: get Objet de fichier dans le rappel de FileReader

 
var div = document.createElement('div'); 
div.ondrop = function(e) { 
    e.preventDefault(); 
    e.stopPropagation(); 
    var files = e.dataTransfer.files; 
    for (var i=0; i<files.length; i++) { 
    var file = files[i]; // this is the file I want!! 
    var filereader = new FileReader(); 
    filereader.onload = function(e) { 
     this; // the FileReader object 
     e.target; // the same FileReader object 
     this.result; // the dataURL, something like data:image/jpeg;base64,..... 
     var img = document.createElement('img'); 
     img.src = this.result; 
     img.title = file.fileName; // This won't be working 
     document.appendChild(img); 
    } 
    } 
    return false; 
} 

Qu'est-ce que je pouvais faire - ce que je fais en ce moment - est envelopper le contenu de la boucle dans une fonction et d'exécuter pour créer un nouveau champ d'application et de garder un fichier dans cette portée comme si:

 
    for (var i=0; i<files.length; i++) { 
    var _file = files[i]; // this is the file I want!! 
    (function(file) { 
     // do FileReader stuff here 
    })(_file); 
    } 

Je me demandais juste ... Peut-être qu'il me manque quelque chose. Est-il possible d'obtenir l'objet File à partir de la fonction onload de FileReader? Les deux this et e.target sont l'objet FileReader et non le fichier. Y at-il quelque chose dans this ou e qui est le fichier ?? Je ne peux pas trouver :(

Merci un bouquet

PS violon:... http://jsfiddle.net/rudiedirkx/ZWMRd/1/

Répondre

22

Je l'ai déjà trouvé un moyen peut-être pas mieux que l'emballage de la portée, mais je pense qu'il est plus propre:

for (var i=0; i<files.length; i++) { 
    var file = files[i]; // this is the file I want!! 
    var filereader = new FileReader(); 
    filereader.file = file; 
    filereader.onload = function(e) { 
     var file = this.file; // there it is! 
     // do stuff 
    } 
} 

Il y a maintenant une manière beaucoup plus facile (apparemment plus rapide) (synchro!) pour obtenir l'URL de données d'un fichier:

img.src = URL.createObjectURL(file); 

Démonstration sur http://jsfiddle.net/rudiedirkx/ZWMRd/8/show/ des deux méthodes, et le problème original illustré (faites glisser plusieurs images et vérifiez les info-bulles du titre).

-1

Je ne pense pas que this.file soit toujours supporté. Lorsque j'essaie d'exécuter le code de réponse, ce.fichier n'est pas défini alors que si j'exécute le code à partir de la question, j'obtiens les résultats attendus. Je pense que vous devez utiliser la fermeture (au moins c'est comme ça qu'ils le font sur html5rocks (Example)).

+0

Voici ce que j'utilise maintenant (et que j'utilise depuis un moment): http://js1.hotblocks.nl - le javascript: http://js1.hotblocks.nl/tests/ajax/fdd.js - Toujours en utilisant le code dans ma réponse. Et il fonctionne. Sans la fermeture (moche). (Il est commenté avec '//'.) – Rudie

+0

Si vous aimez Javascript, vous pouvez l'utiliser (n'importe quelle partie). Je suis curieux de savoir comment les webworkers pourraient jouer un rôle dans cela (utilisez les webworkers pour que les rappels de chargement d'image les lisent et les affichent avant de les télécharger) – Rudie

+0

J'ai manqué l'affectation de 'filereader.file = file; Merci d'avoir signalé cette solution –