3

Background: I need to load ad scripts after the DOM has loaded. Because many of the scripts use document.write() and other potentially bad functions to run after the DOM has loaded, I want to load the scripts inside an iframe.

So when the ad needs to be shown, an event is triggered which does the following:

        var iframe = document.createElement('iframe');
        iframe.setAttribute('id', 'iframeId');
        iframe.setAttribute('src', 'about:blank');

        var adContainer = document.getElementById('AdContainer');
        adContainer.appendChild(iframe);

        var val = '<html><head></head><body>';
        val += '<scr' + 'ipt type="text/javascript" src="' + url + '"></scr' + 'ipt>';
        val += '</body></html>';

If I don't assign the html and body tags to val, the script automatically gets appended to the head of the iframe and fails to execute in FF. In IE, the script doesn't execute with or without the head/body/html tags.

        var doc = iframe.contentWindow || iframe.contentDocument;

        if (doc.document){
            doc = doc.document
        }

        doc.open();
        doc.write(val);
        doc.close();

I found this last bit of code here: Why does appending a <script> to a dynamically created <iframe> seem to run the script in the parent page?. I do NOT want to load jquery in the iframe though, I just want to append a script and have it execute.

My current solution seems to work great in FF and Webkit. However, IE doesn't execute the script. The script is written to the page, but doesn't start running. Is there a better way to append the script to the iframe so it will run cross browser? Or is it possible to tell IE to run the script?

I know that I could load an external document with the ad script via the iframe, but I don't want to make the extra call to my server if I can do this dynamically. Also, I've tried using appendChild() on the iframe's body to insert the script, but since the script element is created outside the iframe's DOM this doesn't seem to work.

Community
  • 1
  • 1
agmin
  • 71
  • 1
  • 3
  • 1
    So create the script element with the iframe's DOM - you're already getting the document object, so call `doc.createElement("script")` etc – Pointy Jun 15 '10 at 22:31
  • @Pointy Right, I did try that but also unsuccessfully. It looks like the script element is successfully created, but I can't append it anywhere. When I try doc.body.appendChild(script) IE says the "body" is null or not an object. FF just fails quietly (I'm using the module pattern so debugging is a pain). Is there anywhere else I could append the script? I tried both head and body to no avail. – agmin Jun 15 '10 at 23:45
  • Have you tried calling doc.getElementsByTagName('body') to see if that returns anything? – Pointy Jun 15 '10 at 23:47
  • No luck there, I did try that. – agmin Jun 17 '10 at 16:11

2 Answers2

1

IE needs defer="true" in the script tag when it should execute dynamically.

Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453
0

In case no one else has any better ideas, I did discover one solution, albeit a non-ideal one.

As per Michael Kleber's very useful comment here: Why won't this JavaScript (using document.open and document.write) work in Internet Explorer or Opera?, calling

document.close() 

will hang all script execution in IE. Simply omitting that line makes the script execute. I would prefer a solution that doesn't involve leaving the iframe document open, as I don't know what kind of consequences that might entail.

Community
  • 1
  • 1
agmin
  • 71
  • 1
  • 3
  • For future readers, this solution does not work if the remote script written to the iframe via doc.write contains code like this: "document.write('-->');". It interprets the script closing tag as, unsurprisingly, a script closing tag. However, if this same script is loaded on an iframe with a real source, it works fine. I don't know why. – agmin Jun 17 '10 at 16:13