我是JavaScript的新手,jQuery和谷歌没有得到答案。我正在写一个在线电子书阅读器。这是用户可以输入多个epub文件的库的代码,相关信息(如作者)应该显示在表格中。为此,我需要提取ePub文件。 jsZip library完美无缺。内容必须显示在动态创建的表中(因为我不知道文件的数量)。
问题是for循环要快并创建所有单元格中只有name和filesize,并且在for循环完成后,FileReader的onload执行并将所有内容添加到最后一个单元格中。在此代码中,警报(“A”)发生的次数与警报(“B”)发生之前输入的文件一样多。有没有什么方法可以让循环等到FileReader的onload完成?
function handleFileSelect(evt) {
var files = evt.target.files;
var rows = Math.ceil(files.length/3);
var a = 0;
var root = document.getElementById('mainTable');
var tab=document.createElement('table');
tab.style.textAlign = "center";
var row, cell;
var tbo=document.createElement('tbody');
for(var i = 0; i != rows; i++)
{
row=document.createElement('tr');
for(var j = 0; (j < 3);j++)
{
cell = document.createElement('td');
cell.height = "300px";
cell.width = "300px"
if(a <indexes.length)
{
var f = files[a];
var str = f.name;
str = str.substring(0, str.length - 5);
str = "File Name: " + str;
cell.appendChild(document.createTextNode(str));
cell.appendChild(document.createElement('br'));
str = "File Size: " + Math.round(f.size/1024) + " KB";
cell.appendChild(document.createTextNode(str));
cell.appendChild(document.createElement('br'));
var reader = new FileReader();
reader.onload = (function(theFile)
{
return function(e)
{
alert("B");
var zip = new JSZip(e.target.result);
$.each(zip.files, function (index, zipEntry)
{
cell.appendChild(document.createTextNode(zipEntry.name));
cell.appendChild(document.createElement('br'));
//row.appendChild(cell);
});
}
})(f);
reader.readAsArrayBuffer(f);
alert("A");
a++;
}
row.appendChild(cell);
}
tbo.appendChild(row);
}
tab.appendChild(tbo);
root.appendChild(tab);
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
答案 0 :(得分:1)
您的问题是onload处理程序中使用的变量单元格将引用外部循环中分配给单元格的最后一个值。您可以通过将文件处理放在一个单独的函数中来解决这个问题,该函数将创建它自己的范围。
function read_zip_file(f, cell) {
var reader = new FileReader();
reader.onload = (function(theFile)
{
return function(e)
{
alert("B");
var zip = new JSZip(e.target.result);
$.each(zip.files, function (index, zipEntry)
{
cell.appendChild(document.createTextNode(zipEntry.name));
cell.appendChild(document.createElement('br'));
//row.appendChild(cell);
});
}
})(f);
reader.readAsArrayBuffer(f);
}
然后在外部循环中你可以调用:
read_zip_file(f, cell);