我想使用HTML5中的FileReader的API,制作一个人物头像图片上传并预览的功能,在上传的过程中希望依靠FileReader的onprogress事件不断更新进度条的宽度来达到显示进度的状态,进度条用的是bootstrap中的进度条样式。可当我运行时候,发现进度条的宽度只更新一次。我刚开始以为是onprogress事件只运行了一次,于是我在onprogress事件中添加了alert,发现有多个窗口弹出,说明onprogress事件运行正常。除此之外,我还发现,进度条的宽度更新值恰与第一次弹出窗口的值对应,为什么进度条宽度之后不再更新了呢?
html
<div class="col-md-6 col-sm-6 col-xs-6">
<img id="person_pic" src='{{user.pic.url}}' alt="" />
<div id="file" class="form-group">
<label for="{{form.pic.id_for_label}}">更改头像:</label>
{{form.pic}}
{{form.pic.error}}
</div>
<div id="progress" class="progress progress-striped active" hidden="hidden">
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
</div>
js
$("input[type=file]").change(function(){ //上传头像图片预览
var fileobj = $(this)[0];
if (fileobj && fileobj.files[0]){
var headimage = fileobj.files[0]
if (headimage.type.split('/')[0] == 'image'){
if(headimage.size/1024/1024 <= 2 ){
if (typeof FileReader != 'undefined'){
var reader = new FileReader();
reader.onloadstart = function(){
$('#progress').show();
};
reader.onprogress = function(e){ //此处为进度条更新代码
alert(e.loaded/e.total*100+"%");
$("div[role=progressbar]").width(e.loaded/e.total*100+"%");
};
reader.readAsDataURL(headimage);
reader.onload = function(){
var dataURL = reader.result;
$("#person_pic").attr("src",dataURL);
};
}else{
var URL = window.URL || window.webkitURL;
var imageURL = URL.createObjectURL(headimage);
$("#person_pic").attr("src",imageURL);
}
}else{
alert("图片大小必须小于2M")
fileobj.value = '';
}
}else{
alert("上传文件必须为图片格式");
fileobj.value = '';
}
}
});
如图进度条停在一个地方就不动了,然而图片已经读取完毕。
首先你应该在读取开始时把进度条清0:
reader.onloadstart = function(){
$('#progress').show();
$("div[role=progressbar]").width('0px');
};
其次这不是不更新的问题,是由于bootstrap进度条有个transition动画的时间,当你第二次开始读取时进度条是100%变成0,这个transition需要时间过渡到0,而你上传时width又不断增加,导致过渡到0的动画没完成就向增加的宽度过渡了,所以看起来不是从0开始读取的
所以如果想一个进度条多用的话建议自己写样式或者把进度条动画屏蔽