3

I am using HTML 5 FileReader to read more that one file asynchronously.

I would like to keep track of loading of individual files as more that one files can be added at once.

Now i created div with background 0% for each image, but i am not clear about how to pass this division's id or reference in the onprogress event so that i can track progress and update the div content dynamically.

In simple terms let me know about how to ensure that i am updating the correct progress control associated with the file, when multiple files are uploaded simultaneously? I am not getting my JS right.

var up_file = document.getElementById('multiple_file'); 
        if(up_file.files)
        {   
            for(var x=0; x <up_file.files.length; x++)
            {
                //console.log(up_file.files.length);
                var file = up_file.files[x];

                var loadingDiv = document.createElement("div");
                var container = document.getElementById('loading_container');   

                loadingDiv.className = "loading";
                loadingDiv.id ="loading_" + x;
                loadingDiv.innerHTML = '0%';
                container.appendChild(loadingDiv);


                var reader = new FileReader();  

                reader.onprogress = function (evt) {
                  if (evt.lengthComputable) {
                  console.dir(evt);
                    // evt.loaded and evt.total are ProgressEvent properties
                    var loaded = (evt.loaded / evt.total);
                    if (loaded < 1) {
                        console.log(loaded);
                    }
                  }
                }

                var img = document.createElement("img");
                img.className = "hide";
                reader.onload = (function(aimg) {
                    return function(e) {
                        LIB.addEvent(aimg, "load", function(){
                            var scale = 1;
                            scale = aimg.width / 200;
                            aimg.width = aimg.width  / scale;
                            aimg.className = "show";
                        }, false);
                        aimg.src = e.target.result; 
                        var li = document.createElement("li");
                        li.appendChild(aimg);
                        document.getElementById('img_packet').appendChild(li);
                    };
                })(img);
                reader.readAsDataURL(file);
            }
        }

1 Answer 1

4

loadingDiv is still visible inside the onprogress function as a closure is formed. The problem is that it's in a loop, so by the time onprogress is called, loadingDiv will probably have been assigned a new value.

To get around this you can use an extra closure to take a copy of the current value of loadingDiv:

reader.onprogress= function(myloadingdiv) {
    return function(evt) {
        if (evt.lengthComputable)
            myloadingdiv.innerHTML= evt.loaded/evt.total*100+'%';
    };
}(loadingDiv);

In ECMAScript Fifth Edition, the bind() method will does this for you more cleanly:

reader.onprogress= function(myloadingdiv, evt) {
    if (evt.lengthComputable)
        myloadingdiv.innerHTML= evt.loaded/evt.total*100+'%';
}.bind(loadingDiv);

For browsers that don't support bind() yet, you can patch in an implementation thus:

if (!('bind' in Function.prototype)) {
    Function.prototype.bind= function(owner) {
        var that= this;
        if (arguments.length<=1) {
            return function() {
                return that.apply(owner, arguments);
            };
        } else {
            var args= Array.prototype.slice.call(arguments, 1);
            return function() {
                return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
            };
        }
    };
}
Sign up to request clarification or add additional context in comments.

Comments

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.