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

不打扰是莪最后的温柔 提交于 2019-11-26 16:02:54

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!