没有jQuery
所以,我需要一个能够循环检查页面上所有图像的功能。我需要获得他们的尺寸并验证这些。
function checkImageInputs() {
var images = new Array();
var fileInputs = document.getElementsByClassName('file-input');
for (var i = 0; i < fileInputs.length; i++) {
var t = fileInputs[i];
var ourCell = t.parentNode;
if (t.files[0]) {
var file = t.files[0];
fr = new FileReader();
fr.onload = createImage;
fr.readAsDataURL(file);
function createImage() { // Create Image
img = document.createElement('img');
img.src = fr.result;
img.className = 'file-result';
ourCell.appendChild(img);
images[i] = img;
}
}
}
// I need the images array here
alert(images.length);
}
当我将循环添加到我的函数以处理页面上的所有文件输入时,它不会向我返回想要的结果。
alert
返回0,即使我的所有文件输入都填满了图像。
fr.onload
之后alert
执行其功能。
同样适用于ourCell.appendChild(img)
,图片显示在alert
之后。
如何使alert
显示实际的图像数量,等到所有图像都被加载?
我在DOM加载上调用此函数,如下所示:
var fileInputs = document.getElementsByClassName('file-input');
for (var i = 0; i < fileInputs.length; i++) {
fileInputs[i].onchange = new Function('checkImageInputs()');
}
答案 0 :(得分:4)
它是异步的,因此在执行createImage回调之前执行长度评估语句。我注意到的另一件事是你使用循环迭代变量将值设置为数组images
,在该变量中你有条件。因此,任何与条件不匹配的内容都会在该索引处的数组中创建一个洞,因此数组的长度不会反映数组中的实际项目数。所以使用array.push代替并更好地使用Array文字而不是数组构造函数。这是除非您真的想知道图像是否存在。
所以试试这个:
function checkImageInputs(callback) { //take a callback argument
var images = [],
fileInputs = document.getElementsByClassName('file-input'),
left = 0;
for (var i = 0; i < fileInputs.length; i++) {
var t = fileInputs[i];
var ourCell = t.parentNode;
if (t.files[0]) {
var file = t.files[0];
left++; //increment the count
var fr = new FileReader(); //If you don't specify a var keyword here fr becomes global
fr.onload = createImage.bind(this, i); //bind the iteration variable here
fr.readAsDataURL(file);
function createImage(itr) { // Create Image
var img = document.createElement('img'); //If you don't specify a var keyword here img becomes global
img.src = fr.result;
img.className = 'file-result';
ourCell.appendChild(img);
images.push(img);
left--; //decrement left count
if(!left) { //check if this is the last one
callback(images); //now make the call back
}
}
}
}
}
function postProcess(images){
// I need the images array here
alert(images.length);
}
checkImageInputs(postProcess); //provide the callback as argument here.
<强> Fiddle 强>
一个解决方案使用ecmaScript5将function.prototype.bind循环迭代变量用于早期浏览器中不可用的函数,但是你也可以使用链接中提到的脚本修补ith。其他选项用封闭物替换它。
变化
fr.onload = createImage.bind(this, i);
到
fr.onload = (function(i){
return function(){
createImage(i);
}
})(i);
<强> Fiddle 强>