我想在文件夹中加载图像,并想在我的js中获取base64中的所有图像以供将来使用

时间:2017-04-07 22:19:43

标签: javascript filereader

我正面临这个问题我总是得到我的图像数组中的最后一个图像,因为Filereader库函数onloadend的种类。 如何为我的文件夹中的所有图像获取base64。

<input id="file-input" multiple webkitdirectory type="file" />
var input = document.getElementById('file-input');
var file_names = "";
var entries_length = 0;
var entries_count = 0;
var image = new Array();   
var obj = {};
var j = 0;
input.onchange = function(e) {
        var files = e.target.files; // FileList
        entries_length = files.length;
        console.log(files);

        for (var i = 0, f; f = files[i]; ++i){
            console.log("i:"+i);
            entries_count = entries_count + 1;
            //console.debug(files[i].webkitRelativePath);
            if(files[i].type=="image/jpeg")
            {

                var string = files[i].webkitRelativePath;
                var name = string.split("/")[3]; //this is because my image in 3rd dir in the folder
                var reader = new FileReader();
                reader.onloadend = function() {

                        obj.name = string.split("/")[3];
                        obj.image = reader.result;
                        image[j] = obj;
                        j = j+1;

                }
                reader.readAsDataURL(files[i]);

            }

        }
       console.log(image);
    }        

1 个答案:

答案 0 :(得分:0)

问题是由异步加载文件引起的。您遍历数组并每次为阅读器设置onloadend处理程序,然后通过调用readAsDataURL开始加载。

一个问题是,当第一个图像加载时,for循环可能已完成,i已经在数组的最后一个索引处。

此时,从files[i].webkitRelativePath获取路径将为您提供最后的文件名,而不是您期望的文件名。

检查example for readAsDataURL on MDN以查看一个可能的解决方案 - 每个加载都在一个单独的函数中执行,该函数保留其范围以及file.name。不要因他们正在使用的结构而被推迟:[].forEach.call(files, readAndPreview)。这是一种映射文件的方法,这些文件是FileList而不是常规数组(因此列表没有自己的forEach方法)。

因此,将加载逻辑包装在一个以文件对象作为参数的函数中就足够了:

var images = [];

function loadFile(f) {
    var reader = new FileReader();
    reader.onloadend = function () {
        images.push({
            name : f.name, // use whatever naming magic you prefer here
            image : reader.result
        });
    };
    reader.readAsDataURL(f);
}

for (var i=0; i<files.length; i++) {
    loadFile(files[i]);
}

函数的每次调用都“记住”调用它的文件对象,并防止文件名混乱。如果您有兴趣,read up on closures

这也有隔离读者对象的良好效果,因为我有一种潜在的怀疑,虽然你每次迭代创建一个新的“本地”读者,javascript范围规则很奇怪,读者也可能互相干扰(如果一个阅读器正在加载会发生什么,但是在相同的范围内你创建一个具有相同变量名称的新阅读器?不确定。)

现在,您不知道加载所有图像需要多长时间,因此如果您想在此之后立即执行操作,则每次调用onloadend时都必须执行检查。这是异步行为的本质。

顺便说一句,我应该注意,手动跟踪images的最后一个索引({1}}是没有意义的。你应该使用j。手动保存索引可以提供错误的可能性。