3

I want to preview images that the user wants to upload. I have tried to create a canvas for each image to make it easier to work with.

If I select multiple images only the final one shows when all images are meant to be show.

<input type="file" id="browseImages" multiple="multiple" accept="image/*">
<output id="list"></output>

document.getElementById('browseImages').addEventListener('change', handleFileSelect, true);

  function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    // Loop through the FileList and render image files as thumbnails.
    for (var i = 0, f; f = files[i]; i++) {
      // Only process image files.
      if (!f.type.match('image.*')) {
        continue;
      }

    var canvas = document.createElement('canvas');
    canvas.width  = 110;
    canvas.height = 100;
    var ctx = canvas.getContext("2d");
    var img = new Image;
    img.onload = function() {
    ctx.drawImage(img, 0, 0, 100, 100);
}
    img.src = window.URL.createObjectURL(f);
    document.getElementById('list').appendChild(canvas);
    window.URL.revokeObjectURL(f);
    }
  }
M9A
  • 3,168
  • 14
  • 51
  • 79
  • 1
    http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – Teemu Oct 21 '15 at 16:03
  • @Teemu I don't get it... – M9A Oct 21 '15 at 16:58
  • 1
    At the time images' onload handler functions are executed, the `for` loop was finished a long time ago. Hence `img` and `ctx` variables in the handlers have the values which were last assigned in the loop. – Teemu Oct 21 '15 at 19:17

1 Answers1

1

Extracting the code to another function you can get all the canvas drawn.

Html code:

<input type="file" id="browseImages" multiple="multiple" accept="image/*">
<output id="list"></output>

Javascript code:

document.getElementById('browseImages').addEventListener('change', handleFileSelect, true);

function handleFileSelect(evt) {                
  var files = evt.target.files; // FileList object

  // Loop through the FileList and render image files as thumbnails.
  for (var i = 0; i < files.length; i++) {
    var f = files[i];
    // Only process image files.
    if (!f.type.match('image.*')) {
      continue;
    }
    createCanvas(f);
  }
}

function createCanvas(f){
  var canvas = document.createElement('canvas');
  canvas.width  = 110;
  canvas.height = 100;
  var ctx = canvas.getContext("2d");
  var img = new Image();
  img.src = window.URL.createObjectURL(f);
  window.URL.revokeObjectURL(f);

  img.onload = function() {
    ctx.drawImage(img, 0, 0, 100, 100);
  }

  document.getElementById('list').appendChild(canvas);
 };

Here is the JSFiddle!

Winner Crespo
  • 1,644
  • 15
  • 29
  • Done the trick! Think I got confused with the closure rules! Thanks for the help – M9A Oct 21 '15 at 21:41