Javascript image.onload 对多张图片仅适用于最后一张图片
Javascript image.onload on multiple image only working for the last image
你好,我对 something.onload 有疑问。我想显示 3 张图像,只要它已经加载。首先,我会将每个图像的容器的不透明度设置为 0,只要它已经加载,我就会将数字更改为 1。
// HTML
<div class="img-container" data-src="imgurl1">
</div>
<div class="img-container" data-src="imgurl2">
</div>
<div class="img-container" data-src="imgurl3">
</div>
// CSS
.img-container{
opacity:0;
width:100%;
}
.loaded {
opacity:1;
}
// JS
window.onload = function(){
var container= document.querySelectorAll('img-container');
for(var i=0;i<container.length;i++){
var temp = container[i];
var img = Image();
img.src = temp.dataset.src;
img.onload = function(){
temp.classList.add('loaded');
};
temp.appendChild(img);
}
}
当我运行那个代码时,只显示最后一张图片。当我检查每张图片时,只有最后一张不透明度 = 1 的图片(class 已成功加载),而另一张图片的不透明度仍然为 0。
我是否遗漏了一些 JS 概念?
提前致谢!!!
使用 Array#forEach
,因为 for-loop
不会为变量创建范围,因此变量将在迭代后被覆盖,并且由于 onload
是异步的,只有最后一张图像会受到影响。
window.onload = function() {
var container = document.querySelectorAll('img-container');
[].forEach.call(container, function(temp) {
var img = Image();
img.src = temp.dataset.src;
img.onload = function() {
temp.classList.add('loaded');
};
temp.appendChild(img);
});
}
这是一个典型的闭包案例。
您的情况如下:
您的 for 循环将同步执行,onload 事件将由 javascript 使用事件队列处理。
所以从技术上讲,您的 for 循环完成执行,然后事件队列中的任何事件都是 executed.Therefore 它只运行 i = 最后一次迭代
为了克服这个问题,您需要使您的函数成为一个 IIFE,并且 return 一个执行所需内容的函数:
window.onload = function(){
var container= document.querySelectorAll('img-container');
for(var i=0;i<container.length;i++){
img.onload = (function(){
return function(){
var temp = container[i];
var img = Image();
img.src = temp.dataset.src;
temp.classList.add('loaded');
temp.appendChild(img);
}
})(i);
}
}
你好,我对 something.onload 有疑问。我想显示 3 张图像,只要它已经加载。首先,我会将每个图像的容器的不透明度设置为 0,只要它已经加载,我就会将数字更改为 1。
// HTML
<div class="img-container" data-src="imgurl1">
</div>
<div class="img-container" data-src="imgurl2">
</div>
<div class="img-container" data-src="imgurl3">
</div>
// CSS
.img-container{
opacity:0;
width:100%;
}
.loaded {
opacity:1;
}
// JS
window.onload = function(){
var container= document.querySelectorAll('img-container');
for(var i=0;i<container.length;i++){
var temp = container[i];
var img = Image();
img.src = temp.dataset.src;
img.onload = function(){
temp.classList.add('loaded');
};
temp.appendChild(img);
}
}
当我运行那个代码时,只显示最后一张图片。当我检查每张图片时,只有最后一张不透明度 = 1 的图片(class 已成功加载),而另一张图片的不透明度仍然为 0。
我是否遗漏了一些 JS 概念? 提前致谢!!!
使用 Array#forEach
,因为 for-loop
不会为变量创建范围,因此变量将在迭代后被覆盖,并且由于 onload
是异步的,只有最后一张图像会受到影响。
window.onload = function() {
var container = document.querySelectorAll('img-container');
[].forEach.call(container, function(temp) {
var img = Image();
img.src = temp.dataset.src;
img.onload = function() {
temp.classList.add('loaded');
};
temp.appendChild(img);
});
}
这是一个典型的闭包案例。
您的情况如下: 您的 for 循环将同步执行,onload 事件将由 javascript 使用事件队列处理。
所以从技术上讲,您的 for 循环完成执行,然后事件队列中的任何事件都是 executed.Therefore 它只运行 i = 最后一次迭代
为了克服这个问题,您需要使您的函数成为一个 IIFE,并且 return 一个执行所需内容的函数:
window.onload = function(){
var container= document.querySelectorAll('img-container');
for(var i=0;i<container.length;i++){
img.onload = (function(){
return function(){
var temp = container[i];
var img = Image();
img.src = temp.dataset.src;
temp.classList.add('loaded');
temp.appendChild(img);
}
})(i);
}
}