您好我正在尝试使用FileReader实现创建多个文件上传预览的脚本。 这是我的出发点
<input id="attachments" type="file" multiple="multiple" name="attachments">
<table id="file_info_attachments" class="table table-preview"></table>
我想要做的是阅读上传的文件列表,将它们的名称和大小放入file_info_attachments表(每个文件一行),而棘手的部分,如果它们是图像,则在同一行添加预览。
我理想的预览应该是这样的
<input id="attachments" type="file" multiple="multiple" name="attachments">
<table id="file_info_attachments" class="table table-preview">
<tr>
<td>No preview</td>
<td>file_1.txt</td>
<td>2000</td>
</tr>
<tr>
<td><img src="[IMAGE DATA]" /></td>
<td>file_2.png</td>
<td>2000</td>
</tr>
</table>
我的解析函数划痕如下:
function parseFiles(files, id) {
$("#file_info_" + id).html("");
if(files.length > 0) {
for (var i = 0; i < files.length; i++) {
$("#file_info_" + id).append("<tr><td class=\"preview preview_" + i + "\">No preview</td><td>" + files[i].name + "</td><td>Size: " + files[i].size + "</td></tr>");
if(/\.(jpe?g|png|gif)$/i.test(files[i].name) && typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function(e){
//obviously I cannot do that this way due to how reader.onload works
//$("#file_info_" + id + " .preview_" + i).html("<img src=\"" + e.target.result + "\" />");
};
reader.readAsDataURL(files[i]);
}
}
}
}
这就是我调用parseFiles函数的方式:
$(document).on("change", "#attachments", function(){
var files = $(this)[0].files;
parseFiles(files, "attachments");
});
我知道我可以通过将信息行附加到reader.onload函数而不是在循环之后添加它来使其工作但是,因为我正在处理不同类型的文件,所以我只想保持它们的顺序和只需更新预览字段,以防它们是图像。 我怎样才能使reader.onload通过添加更新我的预览的内部HTML
提前完成。
答案 0 :(得分:5)
不确定浏览器是否会保留用户选择多个文件的顺序 Actualy我非常有信心在我的FF上按字母顺序排序,但要以相同的顺序显示图像当你进入input.files
财产时,
根本不使用FileReader读取用户选择的文件。
相反,您应该更喜欢URL.createObjectURL()
方法。
此方法是同步的,因此您不必处理不同的范围,对于用户选择的文件,,这只是指向存储在用户系统中的文件的直接指针,即内存影响几乎为0。
file.onchange = function(e) {
for (let i = 0; i < this.files.length; i++) {
let url = URL.createObjectURL(this.files[i]);
let img = new Image();
img.src = url;
document.body.appendChild(img);
// you can even free these 10bits you occupy in memory if you don't need the url anymore
img.onload = function() {
URL.revokeObjectURL(this.src);
}
console.log(this.files[i].name);
}
}
&#13;
<input type="file" accept="image/*" multiple id="file">
&#13;