我一直在预览多张图片,然后才上传并尝试使用@ ratan-paul对"Preview an image before it is uploaded"的响应非常有用。但是,当我尝试稍微调整代码时,我得到了一个相当意外的结果。我所做的是为每个<span>
创建一个<image>
标记,以添加一些样式选项。这是我最终得到的jQuery代码:
$(function () {
var span_id = "";
function readURL(input) {
for(var i =0; i< input.files.length; i++){
var span = $('<span>');
span_id = "span"+i;
span.attr('id',span_id);
span.appendTo('#img-previews');
if (input.files[i]) {
var reader = new FileReader();
reader.onload = function (e) {
var img = $('<img id="dynamic">');
img.attr('src', e.target.result);
img.attr('height','150px');
img.attr('width','200px');
img.appendTo("#"+span_id);
};
reader.readAsDataURL(input.files[i]);
}
}
}
$("#imgUpload").change(function(){
readURL(this);
});
});
现在奇怪的是,当我运行上面的代码时,我为每个图像创建了一个<span>
标记,但所有图像都被塞进了最后创建的<span>
。另一方面,如果我调试脚本,我会得到想要的结果,其中每个图像都插入到自己的<span>
标记中。我对此感到困惑,所以如果有人对于为什么会发生这种情况有任何想法,或者如何避免它,那将非常感谢你的帮助。
答案 0 :(得分:1)
短篇小说:
将循环更改为
for(let i =0; i< input.files.length; i++){
注意,let
循环中的for
可能无法像IE11和Edge那样工作。您可以将跨度的创建移动到reader.onload
事件中以调整这些浏览器(但您的id代将不得不改变)。
长篇故事:
使用var i =0
在整个循环中实例化i
,而let i =0
将其绑定到当前迭代。
正在发生的事情是for
循环触发了异步调用reader.onload
,该异步调用被添加到JS事件循环以供将来解析,并且for
循环继续进行下一次迭代。 重要位:在下一次迭代中,之前的reader.onload
尚未解决。
稍后,{/ 1}}异步调用在 for循环完成后返回(其中reader.onload
处于循环的最大值),并追加结果{ {1}}到i
。
更新:好的,所以img
可能无法在任何地方得到支持,截至2017年7月,caniuse将其置于80%。
要获得一致的结果,请将#span_(max i)
元素的创建移至let
事件:
span
请注意,这些onload
元素的创建最终可能会出现故障;如果您在添加时按顺序添加它们,请查看使用Promise.all(或jQuery版本)。
另请注意,我没有对上述情况进行测试,因此可能需要进行一些按摩。