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

时间:2016-03-03 10:14:58

标签: javascript jquery html onload

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

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

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

我们的想法是等到两个iframe都完全加载,然后警告"加载" - 当然这是一个简化的例子,为了堆栈。

该脚本位于html doc正文末尾的脚本标记中。

3 个答案:

答案 0 :(得分:4)

@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 上设置新活动。当它的内容发生变化时,它会在左上方和右上方发射事件,并在你想要的地方发出声音!

最好的方法是跟踪你加载的是哪些。加载完毕后,您只需运行该功能。

答案 1 :(得分:3)

问题是,在为#iframe1加载附加处理程序之前,您需要等待#iframe2加载。因此,如果首先加载#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!');
    }
});

答案 2 :(得分:2)

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

~function () {
  var loaded = 0;

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