如何将其他参数传递给javascript事件对象?

时间:2010-09-03 09:20:50

标签: javascript html5

我正在使用HTML 5 FileReader异步读取多个文件。

我想跟踪单个文件的加载,因为可以一次添加一个文件。

现在我为每个图像创建了背景为0%的div,但我不清楚如何在onprogress事件中传递此分区的id或引用,以便我可以跟踪进度并动态更新div内容。

简单来说,让我知道在同时上传多个文件时如何确保我正在更新与文件关联的正确进度控制?我没有让我的JS正确。

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 个答案:

答案 0 :(得分:4)

在形成闭包时,loadingDiv函数内部仍然可以看到

onprogress。问题是它处于循环中,所以在调用onprogress时,loadingDiv可能会被分配一个新值。

要解决此问题,您可以使用额外的闭包来获取loadingDiv的当前值的副本:

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

在ECMAScript第五版中,bind()方法会更干净地为您完成此任务:

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

对于尚不支持bind()的浏览器,您可以在实现中修补:

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