我正在使用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);
}
}
答案 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)));
};
}
};
}