Why does appending a <script> to a dynamically created <iframe> seem to run the script in the parent page? Why does appending a <script> to a dynamically created <iframe> seem to run the script in the parent page? javascript javascript

Why does appending a <script> to a dynamically created <iframe> seem to run the script in the parent page?


Had the same problem, took me hours to find the solution.You just need to create the script's object using the iframe's document.

var myIframe = document.getElementById("myIframeId");var script = myIframe.contentWindow.document.createElement("script");script.type = "text/javascript";script.src = src;myIframe.contentWindow.document.body.appendChild(script);

Works like a charm!


I didn't find an answer to my original question, but I did find another approach that works even better (at least for my purposes).

This doesn't use jQuery on the parent page (which is actually a good thing, as I'd prefer not to load it there), but it does load jQuery in the <iframe> in an apparently completely valid and usable way. All I'm doing is writing over the <iframe>'s document object with a new one created from scratch. This allows me to simply include a <script> element in a string which I then write to the <iframe>'s document object.

The code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">  <head>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>    <title>frame</title>  </head>  <body>    <div id="test"></div>    <script type="text/javascript">      // create a new <iframe> element      var iframe = document.createElement('iframe');      // append the new element to the <div id="bucket"></div>      var bucket = document.getElementById('test');      bucket.appendChild(iframe);      // create a string to use as a new document object      var val = '<scr' + 'ipt type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></scr' + 'ipt>';      val += '<scr' + 'ipt type="text/javascript"> $(function() { $("body").append("<h1>It works!</h1>"); }); </scr' + 'ipt>';      // get a handle on the <iframe>d document (in a cross-browser way)      var doc = iframe.contentWindow || iframe.contentDocument;      if (doc.document) {        doc = doc.document;      }      // open, write content to, and close the document      doc.open();      doc.write(val);      doc.close();    </script>  </body></html>

I hope this helps someone down the road!


The answer to the original question is simple - the execution of the script is done by jquery, and since jquery is loaded in the top frame, this is where the script runs too, no matter where you are appending it. A smarter implementation of jquery can no doubt be made to use the correct window object, but for now things are how they are.

As to the workarounds, you already have two good answers (even if one is your own). What I might add is that you can use one of those workarounds to include jquery.js in the iframe, and then get that jquery object instead of the top one to insert your additional markup... but that may very well be overkill too.