简体   繁体   English

onload与ifEventListener('load')的iframe行为

[英]iframe behaviour of onload vs addEventListener('load')

I've been playing around with adding hidden iframe elements to a page, and I want to manipulate the DOM of the these once loaded. 我一直在玩将隐藏的iframe元素添加到页面中,并且我希望在加载后操纵这些元素的DOM。 I've noticed that I can't start manipulating the DOM immediately after adding the iframe to a page since it hasn't loaded yet. 我注意到,在将iframe添加到页面后,我无法立即开始操作DOM,因为它还没有加载。 This can't be done with the DOMContentLoaded event since that fires against the document which doesn't exist in the iframe until it is added to the page, so we have to use the load event. 这不能通过DOMContentLoaded事件来完成,因为它会触发iframe中不存在的文档,直到它被添加到页面中,因此我们必须使用load事件。

Here is some test code: 这是一些测试代码:

var iframe = document.createElement('iframe');
iframe.onload = function() { console.log('loaded!'); };
document.getElementsByTagName('body')[0].appendChild(iframe);

This works as expected, however when I change it to addEventListener it doesn't even get added to the DOM: 这可以按预期工作,但是当我将其更改为addEventListener它甚至不会添加到DOM:

var iframe = document.createElement('iframe');
iframe.addEventListener('load', function() { console.log('loaded!'); });
document.getElementsByTagName('body')[0].appendChild(iframe);

I haven't tested attachEvent in IE. 我还没有在IE中测试过attachEvent

Anyone shed any light on this? 有人对此有所了解吗?

addEventListener() function needs 3 arguments! addEventListener()函数需要3个参数! Take a look at https://developer.mozilla.org/en/DOM/element.addEventListener 看看https://developer.mozilla.org/en/DOM/element.addEventListener

The 3rd argument is marked as optional, but then they write: 第三个参数被标记为可选,但随后他们写道:

Note that this parameter is not optional in all browser versions. 请注意,此参数在所有浏览器版本中都不是可选的。

I'm not sure when and where it is required, but my tests on FF4 threw an exception when calling the addEventListener with 2 arguments: 我不确定它何时何地需要,但我在FF4上的测试在调用带有2个参数的addEventListener时抛出异常:

uncaught exception: [Exception... "Not enough arguments" nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)" location: "JS frame :: http://localhost/index.php :: :: line 10" data: no] 未捕获的异常:[异常......“参数不够”nsresult:“0x80570001(NS_ERROR_XPC_NOT_ENOUGH_ARGS)”位置:“JS frame :: http://localhost/index.php :: :: line 10”数据:否]

By the way, your code works well in Chrome [the string loaded! 顺便说一下,你的代码在Chrome中运行良好[ loaded!了字符串loaded! is logged in console]. 登录控制台]。

Like FF, IE9 needs the 3rd argument in the standards mode (with <!DOCTYPE html> ). 与FF一样,IE9需要标准模式中的第三个参数(使用<!DOCTYPE html> )。 IE9 is the first IE that supports W3C's event model. IE9是第一个支持W3C事件模型的IE。 So in the earlier versions we need to try attachEvent . 所以在早期版本中我们需要尝试attachEvent I don't have earlier IEs, but it worked in IE7/8 Standards Mode and even in Quirks Mode in IE9. 我没有早期的IE,但它在IE7 / 8标准模式下工作,甚至在IE9中的Quirks模式下工作。 Here is the code I used: 这是我使用的代码:

<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<script>
    window.onload=function(){
        var iframe = document.createElement('iframe');
        var func = function() { console.log('loaded!');};
        if(iframe.addEventListener)
            iframe.addEventListener('load', func, true);
        else if(iframe.attachEvent)
            iframe.attachEvent('onload',func);
        document.body.appendChild(iframe);
    }
</script>
</body>
</html>

This is working for me: 这对我有用:

html: HTML:

iframe source code: <br />
<textarea id="output" rows="20" cols="60">loading ...</textarea>

javascript (on documentReady): javascript(在documentReady上):

var iframe = document.createElement('iframe');
iframe.id = iframe.name = "testframe";
iframe.src = "http://fiddle.jshell.net";
iframe.width = 400;
iframe.height = 100;
iframe.style.display = "none";

if (iframe.addEventListener)
    iframe.addEventListener("load", loaded, false);
else
    iframe.attachEvent("onload", loaded);

function loaded() {
    var html;
    if (iframe.contentDocument)
        html = iframe.contentDocument.getElementsByTagName("HTML")[0].innerHTML;
    else
        html = window.frames[iframe.name].document.getElementsByTagName("html")[0].innerHTML;

    document.getElementById("output").value = html;
}

document.getElementsByTagName("body")[0].appendChild(iframe);

See the Demo at: http://jsfiddle.net/WcKEz/ 参见演示: http//jsfiddle.net/WcKEz/

Works with addEventListener, but includes the fallback to attachEvent. 与addEventListener一起使用,但包括attachEvent的回退。 Access to the DOM of the IFRAME of course only on the same domain. 当然,只能在同一个域上访问IFRAME的DOM。

Does the first example work? 第一个例子有用吗? Not sure exactly what you're looking for, but this should illuminate when events work: jQuery document.ready source 不确定你正在寻找什么,但这应该说明事件何时起作用:jQuery document.ready source

$(document).ready equivalent without jQuery 没有jQuery的$(document).ready等价

addEventListener does not work in IE, so if that's where you're testing, then the 2nd would fail before the iframe gets appended. addEventListener在IE中不起作用,所以如果你正在测试它,那么第二个会在iframe被追加之前失败。

You could also add a callback from the page itself, though (for example, using jQuery so you don't reinvent the wheel) I suspect $(iframe).ready() {..} would give you consistent behavior. 你也可以从页面本身添加一个回调(例如,使用jQuery,所以你不要重新发明轮子)我怀疑$(iframe).ready() {..}会给你一致的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM