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);

   }
}