为什么追加一个<script>到一个dynamic创build的<iframe>似乎在父页面上运行脚本?
我试图用JavaScript创build一个<iframe>,然后在<iframe> d文档的上下文中添加一个<script>元素到<iframe>。
不幸的是,似乎我做错了 – 我的JavaScript似乎执行成功,但<script>的上下文是父页面,而不是<iframe> d文档。 当浏览器请求iframe_test.js时 ,我也在Firebug的“Net”选项卡中得到一个301错误,虽然它然后再次请求它(不知道为什么?)成功。
这是我正在使用的代码(现场演示http://onespot.wsj.com/static/iframe_test.html ):
iframe_test.html
<!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><iframe> test</title> </head> <body> <div id="bucket"></div> <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script> <script type="text/javascript"> $(document).ready(function() { $('#bucket').append('<iframe id="test"></iframe>'); setTimeout(function() { var iframe_body = $('#test').contents().find('body'); iframe_body.append('<scr' + 'ipt type="text/javascript" src="http://onespot.wsj.com/static/iframe_test.js"></scr' + 'ipt>'); }, 100); }); </script> </body> </html>
iframe_test.js
$(function() { var test = '<p>Shouldn\'t this be inside the <iframe>?</p>'; $('body').append(test); });
有一点似乎不寻常的是, iframe_test.js中的代码甚至可以工作。 我没有在<iframe>本身加载jQuery,只在父文档中。 这似乎是对我的线索,但我无法弄清楚它是什么意思。
任何想法,build议等将不胜感激!
有同样的问题,花了我几个小时find解决办法。 您只需要使用iframe的文档来创build脚本的对象。
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);
奇迹般有效!
我没有find我原来的问题的答案,但我确实find了另一种更好的方法(至less对我而言)。
这不会在父页面上使用jQuery(这实际上是一件好事,因为我不希望在那里加载它),但它确实以明显完全有效和可用的方式在<iframe>中加载jQuery。 我所做的只是从头开始创build一个新的<iframe>的文档对象。 这允许我简单地将一个<script>元素包含在一个string中,然后写入<iframe>的文档对象。
代码:
<!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>
我希望这可以帮助一个人在路上!
原始问题的答案很简单 – 脚本的执行由jquery完成,由于jquery被加载到顶部框架,所以脚本运行的地方也是这样,无论你在哪里添加它。 jQuery的更聪明的实现无疑可以使用正确的窗口对象,但现在事情是这样的。
至于解决方法,你已经有了两个很好的答案(即使是你自己的)。 我可以添加的是,您可以使用这些解决方法之一,将jquery.js包含在iframe中,然后获取该jquery对象,而不是顶级的插入您的额外标记…但也可能是矫枉过正。