Javascript onload 与 addEventListener('load') 的 iframe 行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5220840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iframe behaviour of onload vs addEventListener('load')
提问by roryf
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. 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. 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.
我一直在尝试向页面添加隐藏的 iframe 元素,并且我想操纵这些加载后的 DOM。我注意到在将 iframe 添加到页面后我无法立即开始操作 DOM,因为它尚未加载。这不能用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.
我还没有attachEvent
在 IE 中测试过。
Anyone shed any light on this?
有人对此有所了解吗?
回答by Hrant Khachatrian
addEventListener()
function needs 3 arguments! Take a look at https://developer.mozilla.org/en/DOM/element.addEventListener
addEventListener()
函数需要3个参数!看看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 上的测试在调用addEventListener
带有 2 个参数的时抛出了异常:
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框架:: http://localhost/index.php:: :: line 10”数据:否]
By the way, your code works well in Chrome [the string loaded!
is logged in console].
顺便说一句,您的代码在 Chrome 中运行良好 [字符串loaded!
已记录在控制台中]。
Like FF, IE9 needs the 3rd argument in the standards mode (with <!DOCTYPE html>
). IE9 is the first IE that supports W3C's event model. So in the earlier versions we need to try attachEvent
. I don't have earlier IEs, but it worked in IE7/8 Standards Mode and even in Quirks Mode in IE9. Here is the code I used:
与 FF 一样,IE9 在标准模式下需要第三个参数(带<!DOCTYPE html>
)。IE9 是第一个支持 W3C 事件模型的 IE。所以在早期版本中我们需要尝试attachEvent
. 我没有早期的 IE,但它在 IE7/8 标准模式下工作,甚至在 IE9 中的 Quirks 模式下工作。这是我使用的代码:
<!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>
回答by roberkules
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. Access to the DOM of the IFRAME of course only on the same domain.
与 addEventListener 一起使用,但包括对 attachEvent 的回退。访问 IFRAME 的 DOM 当然只能在同一个域上。
回答by Jamie Treworgy
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
$(document).ready 相当于没有 jQuery
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() {..}
会给你一致的行为。