Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iframe behaviour of onload vs addEventListener('load')

Tags:

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.

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?

like image 806
roryf Avatar asked Mar 07 '11 14:03

roryf


People also ask

Does iframe have onload?

Execute a JavaScript Function on a Load of an iFrameWe can use the onload event handler of the iframe HTML tag. The event fires once all the elements in the iframe is loaded. These include a loading of scripts, images, links, subframes etc.

How do I know if an iframe is loaded?

To check if iframe is loaded or it has a content with JavaScript, we can set the iframe's onload property to a function that runs when the iframe is loaded. document. querySelector("iframe"). onload = () => { console.


2 Answers

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>
like image 142
Hrant Khachatrian Avatar answered Oct 16 '22 18:10

Hrant Khachatrian


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.

like image 27
roberkules Avatar answered Oct 16 '22 16:10

roberkules