IE浏览器中iFrame的加载事件未被触发

24

load事件为何在IE中不会对iFrame触发?

请查看这个示例

在Firefox和Chrome中正常工作,但IE失败。

7个回答

27
我认为在Internet Explorer中的iframes中,你无法通过编程方式设置事件处理程序(onload),你需要在你的标记中指定它。

类似以下这样:

<iframe id="myFrame" onload="myFunction();"></iframe>
否则,IE 将忽略该函数。

2
顺便提一下,jQuery绑定的事件在我的FF中也不起作用,指定onload按预期工作。 - Ev Dolzhenko
2
我似乎无法让这在IE10中工作。onload="alert('moo');"没有弹出警告。 - Montana Harkin

3

在添加处理程序之前,IE可能已经加载了内容(并触发了事件)。当我通过jquery静态指定iframe src属性并添加$(x).load事件处理程序时,我发现火狐(3.6.28)会触发我的处理程序,但IE(8.0.6001.18702)不会。

最终,我调整了我的测试程序,以便在添加$(x).load处理程序后通过javascript设置iframe src。我的$(x).load处理程序在IE和Firefox中的相同点被调用(但请注意,通过iframe onload属性添加的处理程序在IE和FF之间行为不同)。这是我最终得到的结果:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script type="text/javascript" src="jquery-ui/js/jquery-1.6.2.min.js"></script>

<script language="javascript">

function show_body(name, $iframe) {
  $('.log').append(name+': '+$iframe.contents().find('body').html()+'<br/>');
}

function actuallyLoaded(name, x) {
  $('.log').append(name+' actually loaded<br/>');
}

$(document).ready(function(){
  $('.i1').load(function(){show_body('i1', $('.i1'));});
  $('.i1').attr('src', 'eb_mce_iframe_content.html');
  var $x=$('.i1').clone().removeClass('i1');
  $('body').append($x);
  $x.load(function(){show_body('x', $x);});
  $x.attr('src', 'eb_mce_iframe_content.html');
});

</script>

</head>
<body>

<iframe class="i1" onload="actuallyLoaded($(this).attr('class')+'/'+$(this).attr('src'), this);">
</iframe>

<div class="log">
</div>

</body>
</html>

以下是Firefox的“日志”:

i1/eb_mce_iframe_content.html已经加载 i1:

这里是Fred狐狸。

/eb_mce_iframe_content.html已经加载 x:

这里还是Fred狐狸。


1
我使用 readystatechange 事件来处理IE浏览器。
var $iframe = $("<iframe>");
$iframe.on("load readystatechange", callback);

适用于ie 11! - Th3B0Y

1

将处理程序直接分配给onload在Chrome、FF和IE(已在IE 8上测试)中有效。

(function (selector) {
    var frame = $(selector).get(0);

    if (frame) {
        frame.onload = function () {
            alert('frame loaded.');
        };
    }
})('#myframe');

1

如果你将这里的JavaScript代码与jQuery一起使用,并将if ($.browser.safari || $.browser.opera) {这一行改为if ($.browser.safari || $.browser.opera || $.browser.msie) {,那么它就可以正常工作了。因此,你会得到以下代码:

$(function(){

    var iFrames = $('iframe');

    function iResize() {

        for (var i = 0, j = iFrames.length; i < j; i++) {
          iFrames[i].style.height = iFrames[i].contentWindow.document.body.offsetHeight + 'px';}
        }

        if ($.browser.safari || $.browser.opera || $.browser.msie) { 

           iFrames.load(function(){
               setTimeout(iResize, 0);
           });

           for (var i = 0, j = iFrames.length; i < j; i++) {
                var iSource = iFrames[i].src;
                iFrames[i].src = '';
                iFrames[i].src = iSource;
           }

        } else {
           iFrames.load(function() { 
               this.style.height = this.contentWindow.document.body.offsetHeight + 'px';
           });
        }

    });

适用于IE7和Chrome的版本,其他浏览器未做检查。谢谢! - MaciejLisCK

0

在你的id前面添加前缀“iframe”:

$('iframe#myFrame').load(function() {
  ...
});

或者尝试使用“ready”代替“load”:

$('#myFrame').ready(function()  {
    alert("Loaded");
});

这应该可以工作。


谢谢,但是“ready”事件在iFrame的内容加载之前就被触发了... - Muleskinner
5
将其指定为选择器中的 iframe 对建议本身并没有逻辑。这个假设是什么 - 它会被更多地选中吗?至于这如何等同于“ready”事件...让人难以理解。 - Barney
ready事件不适用于iframe文档,请参见https://dev.jquery.com/ticket/5511。 - dude

0

Seis的答案是正确的,可以改进为使用非全局/匿名函数。

window.dummy_for_ie7 = function() { }
var iframe = $('<iframe onload="dummy_for_ie7" />')[0];
iframe.attachEvent('onload', real_event_handler)

令我惊讶的是,这个有效。
注意:即便通过那个 hack,iframe.onload = func() 也不会生效。你必须使用 attachEvent。真是让人费解。
注意:自然地,这段代码逐字逐句不会在符合标准的用户代理中工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接