这是我的每个循环: -
var image_obj = {};
$(".wrapper").each(function (index, data) {
var dfile = this.getElementsByClassName('image')[0];
file = dfile.files[0];
if(file != null) {
var fr = new FileReader();
fr.onload = function (e) {
img = new Image();
img.onload = function (k) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
objindex = "obj_" + index;
image_obj[objindex] = canvas.toDataURL("image/jpeg");
};
img.src = fr.result;
};
fr.readAsDataURL(file);
}
});
我需要每个循环的索引将base_64编码图像保存到对象。
但是索引没有按顺序显示,因为每个循环执行在到达canvas.getContext("2d");
之前完成。
答案 0 :(得分:0)
一个大问题是你需要在你的外部函数中声明img
:
$(".wrapper").each(function (index, data) {
var img;
原因是,img
是全球性的。在img
函数中捕获的onload
变量只包含该全局的当前值,这正是最近的each
调用分配给它的任何内容(可能是jquery对象中的最后一个包装器) )。然后,当调用onload
时,它会将错误的图像写入画布。通过声明变量,您可以确保每个外部函数作用域都有自己的img
变量,以便捕获onload
函数,然后在实际应用它们时使用它们。
修改如果您想确保输出的订单是正确的,那么您最后应该对其进行排序,因为您在onload
运行时无法控制;这实际上是它的美丽。我做这样的事情:
ctx.drawImage(img, 0, 0);
if (typeof(image_obj.images) == "undefined")
image_obj.images = [];
image_obj.images[index] = canvas.toDataURL("image/jpeg");
或者只是让image_obj
本身成为一个数组,然后执行:
ctx.drawImage(img, 0, 0);
image_arr[index] = canvas.toDataURL("image/jpeg");
取决于您是否需要将对象作为其他东西的容器。
由于这是一个数组,而不是一个对象,因此图像将按顺序排列。
修改2
现在的问题是,如果某些文件不在那里,你会在阵列中出现漏洞。让我们不要发生这种情况:
var index = -1;
$(".wrapper").each(function (_, data) {
...
if(file != null) {
var fr = new FileReader();
index++;
var localIndex = index; //to capture locally
fr.onload = function (e) {
...
ctx.drawImage(img, 0, 0);
image_arr[localIndex] = canvas.toDataURL("image/jpeg");
..