1

没有 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()');
}
4

1 回答 1

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.

小提琴

一种解决方案使用 ecmaScript5 来function.prototype.bind循环迭代变量到在早期浏览器中不可用的函数,但您也可以使用链接中提到的脚本对其进行修补。其他选项将其替换为闭包。

改变

fr.onload = createImage.bind(this, i);

fr.onload = (function(i){
            return function(){
                createImage(i);
            }              
        })(i);

小提琴

于 2013-09-21T19:50:01.250 回答