开发者

How to pass additional parameters to javascript event object?

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('multi开发者_StackOverflow中文版ple_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);
            }
        }


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜