我的测试代码:
var imageUploadPreview = function (e) {
var input = document.getElementById("file"),
files = e.target.files;
for (var i = 0; i < files.length; i++) {
if (input.files) {
var file = files[i],
reader = new FileReader();
reader.onload = function (e) {
(function (i) {
var img = $('<img>').prop('id', 'img_' + i)
.prop('src', e.target.result).css({'width':'60px', 'height':'60px'});
var div = $('<div>').append(img).append(img.prop('id'))
$('body').append(div);
})(i)
}
reader.readAsDataURL(file);
}
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="file" onchange="imageUploadPreview(event)" multiple />
它的工作原理除外:所有图像ID都是 img_ + files.length
你能解释一下为什么吗?循环会发生什么?答案 0 :(得分:3)
你几乎用iife执行i,你需要把它移到onload之外。问题是onload是异步调用的,所以当它运行时循环就完成了。这就是i
是每个文件的最后一个索引的原因。你需要在onload运行之前执行iife。
reader.onload = function (e) {
(function (i) {
var img = $('<img>').prop('id', 'img_' + i)
.prop('src', e.target.result).css({'width':'60px', 'height':'60px'});
var div = $('<div>').append(img).append(img.prop('id'))
$('body').append(div);
})(i)
}
到
(function (i) {
reader.onload = function (e) {
var img = $('<img>').prop('id', 'img_' + i)
.prop('src', e.target.result).css({
'width': '60px',
'height': '60px'
});
var div = $('<div>').append(img).append(img.prop('id'))
$('body').append(div);
}
})(i);
答案 1 :(得分:2)
您对reader.readAsDataURL(file);
的呼叫是异步的。
这意味着reader.onload
函数不会同步执行循环。因此,当执行加载函数时,循环变量的值是不可预测的。
在将循环变量传递给它之后,将reader.onload
与另一个函数封装在一起。
for(i) {
function(loopVar) {
reader.onload = function () {
//use loopVar here
}(i)
}
这里注册循环变量i
作为封装函数的参数。无论何时执行回调函数,该值在传递时仍将保留。