views:

30

answers:

2

Hi, i've met a strange behaviour in Firefox with this simple script:

    <html>
      <head>
        <script type="text/javascript">
            window.setTimeout(function(){
                var ifr=document.createElement("iframe");
                ifr.src="about:blank";
                document.body.appendChild(ifr);
                var doc=ifr.contentDocument || ifr.contentWindow.document,
                    div=doc.createElement("div");
                div.innerHTML="test";
                window.setTimeout(function(){
                    doc.body.appendChild(div);
                },500);
            },500);
        </script>
    </head>
  </html>

This piece of code creates a blank iframe and appends it to the body of the current page, then it creates a div element that contains a simple text and appends it to the body of the iframe.

In every browser (IE, Safari, Chrome, Opera) it works, but in Firefox (i'm using the version 3.6.3) the div does not appear inside the iframe and no error is thrown.

I think that there must be some stupid error somewhere but i can't find it, have you got some idea?

PS: those window.setTimeout are just a simple way to make sure that the dom is loaded in the page and in the iframe.

+3  A: 

You need to wrap the retrieval of the iframe doc in the timeout.

        window.setTimeout(function(){
            var doc=ifr.contentWindow.document || ifr.contentDocument;
            var div=doc.createElement("div");
            div.innerHTML="test";
            doc.body.appendChild(div);
        },500);

See http://jsfiddle.net/xeGSe/1/

Castrohenge
I knew that there was an easy explanation:) thanks this works perfectly
mck89
that isn't an explanation, it's a workaround for the core problem that it doesn't solve completely.
roryf
I did try rewriting it using jQuery but still had to use a timeout. Any ideas - http://jsfiddle.net/xeGSe/2/?
Castrohenge
+1  A: 

Looks like a timing issue that your setTimeout calls aren't catching. Your better off using onload events to ensure elements are truly available (DOMReady would be better but not as easy in IE). Try this:

document.body.onload = function() {
    var iframe = document.createElement("iframe");
    iframe.src = "about:blank";
    iframe.onload = function() {
        var doc = iframe.contentDocument || iframe.contentWindow.document,
            div = doc.createElement("div");
        div.innerHTML="test";
        doc.body.appendChild(div);
    }
    document.body.appendChild(iframe);
}
roryf