iframe behaviour of onload vs addEventListener('load')
Solution 1
addEventListener()
function needs 3 arguments! Take a look at 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:
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]
By the way, your code works well in Chrome [the string loaded!
is logged in console].
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:
<!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>
Solution 2
This is working for me:
html:
iframe source code: <br />
<textarea id="output" rows="20" cols="60">loading ...</textarea>
javascript (on 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/
Works with addEventListener, but includes the fallback to attachEvent. Access to the DOM of the IFRAME of course only on the same domain.
Comments
-
roryf almost 4 years
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 theload
event.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: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.Anyone shed any light on this?
-
roryf about 13 yearsCan't use
ready
event since this requires a document that doesn't exist yet, unless I'm missing something. -
Jamie Treworgy about 13 yearsI'm suggesting using the same logic as jquery document.ready on the iframe element, e.g. like this plugin seems to do: thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin but still not clear if there's something wrong with your first code snippet, are you trying to hook before images are loaded? Alternatively, assuming you control the code in the iframe, you could use document.ready there to callback to a function using parent.
-
roryf about 13 yearsThe first code snippet works correctly (as was stated), however the
onload
property is non-standard (AFAIK) and I just wondered why the standards-compliant way (ignoring IE) wasn't working. The iframe itself does not point to another page, I want to load it up blank and populate the DOM. -
Jamie Treworgy about 13 yearsonload seems to be ok: w3schools.com/jsref/event_frame_onload.asp i kind of missed you were building this whole thing dynamically. Take a look at this... old but maybe will help. bytes.com/topic/javascript/answers/…
-
roryf about 13 yearsFrankly I would put more credit by my morning crap than w3schools (too far? yeah, too far...). But, the other link looks interesting - the person resorted to using document.write which I have a suspicion I may have come across having to use on a project some years ago. Now if only I had the code lying around :(
-
Jamie Treworgy about 13 yearsHaha! Well fair enough.. though I thought his technique looked reasonable (as a way of testing the different ways of accessing the doc). Here's a more detailed blog post along the same lines written by someone who appears to be out of junior high school: thomas.bindzus.me/2007/12/24/adding-dynamic-contents-to-iframes ... it doesn't seem like there's any really clean way to do this.
-
roryf about 13 yearsAnother interesting link. Doesn't answer my original question of why one event handler works vs the other, but could provide a work-around that negates the need for an event handler at all. Thanks!
-
roryf almost 13 yearsI believe your point about the 3rd parameter was exactly the problem, I wasn't getting the error you did but it was probably just being suppressed somehow. I can't recall but clearly I didn't test it in Chrome (silly me...). Nice one, thanks.