17

With the new File API in Javascript you can read files in Javascript to create dataURLs to show clientside pictures clientside. I'm wondering if you can reach the File object within the FileReader's onload callback. I will illustrate this with an example:

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

What I could do - what I do right now - is wrap the contents of the for loop in a function and execute it to create a new scope and keep a file in that scope like so:

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

I was just wondering... Maybe I'm missing something. Is there a way to get the File object from within the onload function of the FileReader? Both this and e.target are the FileReader object and not the File. Is there something in this or e that is the File?? I can't find it :(

Thanks a bunch.

PS. A fiddle: http://jsfiddle.net/rudiedirkx/ZWMRd/1/

2 Answers 2

28

I already found a way. Maybe not better than the scope wrapper, but I think it's neater:

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
    }
}

There is now a much easier (apparently faster) way (sync!) to get a file's data URL:

img.src = URL.createObjectURL(file);

Demo on http://jsfiddle.net/rudiedirkx/ZWMRd/8/show/ of both methods, and the original problem illustrated (drag multiple images and check the title tooltips).

Sign up to request clarification or add additional context in comments.

Comments

-1

I don't think this.file is still supported. When I try to run the answer code, this.file is undefined whereas if I run the code from the question I get the expected results. I think you have to use the closure (at least this is how they do it on html5rocks (Example)).

3 Comments

This is what I use now (and have been using for a while): js1.hotblocks.nl - the javascript: js1.hotblocks.nl/tests/ajax/fdd.js - Still using the code in my answer. And it works. Without the (ugly) closure. (It's commented with //.)
If you like Javascript, you're welcome to use (any part of) it. I'm curious about how webworkers might play a role in this (use webworkers for the image load callbacks to read and display them before uploading)
I missed the assignment of filereader.file = file;. Thanks for pointing out this solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.