在执行函数之前等待加载多个 iFrame

Waiting for multiple iFrames to load before executing function

原谅我的天真,这可能很明显,我现在看不到。

请告诉我以下代码有什么问题:

    $('#iframe1').load(function(){
      $('#iframe2').load(function(){
        alert('loaded!');
      });
    }); 

想法是等到两个 iframe 都加载完毕,然后提醒 "loaded" - 当然这是为了堆栈的简化示例。

脚本位于 html 文档正文末尾的脚本标签中。

问题是您在为 #iframe2 加载附加处理程序之前等待 #iframe1 加载。因此,如果 #iframe2 先加载,您将永远不会收到回调。

相反,请在两者上观看 load 事件并跟踪您看过的事件:

var seen1 = false,
    seen2 = false;
$('#iframe1, #iframe2').load(function(){
    if (this.id == "iframe1") {
        seen1 = true;
    } else {
        seen2 = true;
    }
    if (seen1 && seen2) {
        alert('loaded!');
    }
});

为什么您希望第二个 iframe 在第一个 iframe 之后加载?

~function () {
  var loaded = 0;

  $('#iframe1, #iframe2').load(function (){
    if (++loaded === 2) {
      alert('loaded!');
    }
  });
}()

@Quertiy 的回答非常好,但不是很 jQuery-ish。它仅针对 2 个 iframe 进行硬编码。

jQuery 的美妙之处在于,您可以让它为最多的人服务,同时尽可能减少摩擦。

我推荐了一个非常 非常简单的插件,它几乎可以完成该答案中存在的内容,但以更开放的方式。它不仅适用于 iframe,还适用于图像、音频、视频和任何具有 onload 事件的内容!

事不宜迟,代码如下:

(function($){
    $.fn.extend({allLoaded: function(fn){
        if(!(fn instanceof Function))
        {
            throw new TypeError('fn must be a function');
        }

        var $elems = this;
        var waiting = this.length;

        var handler = function(){
            --waiting;
            if(!waiting)
            {
                setTimeout(fn.bind(window), 4);
            }
        };

        return $elems.one('load.allLoaded', handler);
    }});
})(window.jQuery);

它的工作原理是向该选择中的每个元素添加一个 load 处理程序。因为它是一个插件,所以你可以用任何你决定使用它的方式。

这是一个加载 30 个随机图像的示例:

//plugin code
(function($){
 $.fn.extend({allLoaded: function(fn){
  if(!(fn instanceof Function))
  {
   throw new TypeError('fn must be a function');
  }
  
  var $elems = this;
  var waiting = this.length;
  
  var handler = function(){
   --waiting;
   if(!waiting)
   {
    setTimeout(fn.bind(window), 4);
   }
  };
  
  return $elems.one('load.allLoaded', handler);
 }});
})(window.jQuery);



$(function(){

 //generates the code for the 30 images
 for(var i = 0, html = ''; i < 30; i++)
  html += '<img data-src="http://lorempixel.com/g/400/200/?_=' + Math.random() + '">';
 
 //stuffs the code into the body
 $('#imgs').html(html);
 
 //we select all images now
 $('img')
  .allLoaded(function(){
   //runs when done
   alert('loaded all')
  })
  .each(function(){
   //the image URL is on a `data` attribute, to delay the loading
   this.src = this.getAttribute('data-src')
  })

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>

<div id="imgs"></div>


正如之前多次提到的,您的问题是您的 iframe 附加了一个 load 事件。 每次 内容更改时都会触发该事件。

之后,您在 #iframe2 上设置了 一个新事件。当它的内容发生变化时,它会左右触发事件,超出您的意愿!

最好的方法是跟踪您是否加载了哪些。加载完所有内容后,您只需 运行 函数即可。