Почему добавление <script> к динамически созданному <iframe> похоже на запуск script на родительской странице?

Я пытаюсь создать <iframe> используя JavaScript, затем добавьте <script> элемент к этому <iframe> , который я хочу запустить в контексте документа <iframe> d.

К сожалению, кажется, что я делаю что-то неправильно - мой JavaScript, кажется, успешно выполняется, но контекст <script> это родительская страница, а не документ <iframe> d. Я также получаю 301 Ошибка на вкладке "Нет" Firebug, когда браузер запрашивает iframe_test.js, хотя он снова запрашивает его (не уверен, почему?) Успешно.

Это код, который я использую (live demo at 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>&lt;iframe&gt; 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 &lt;iframe&gt;?</p>';
  $('body').append(test);
});

Одна вещь, которая кажется необычной, заключается в том, что работает код iframe_test.js; Я не загружал jQuery в <iframe> сам, только в родительском документе. Это кажется мне ключом, но я не могу понять, что это значит.

Любые идеи, предложения и т.д. будут высоко оценены!

Ответ 1

Если бы та же проблема, мне потребовалось несколько часов, чтобы найти решение. Вам просто нужно создать объект script, используя документ iframe.

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);

Работает как шарм!

Ответ 2

Я не нашел ответа на свой первоначальный вопрос, но нашел другой подход, который работает еще лучше (по крайней мере для моих целей).

Это не использует jQuery на родительской странице (на самом деле это хорошо, поскольку я бы предпочел не загружать его там), но он загружает jQuery в <iframe> по-видимому, полностью действительным и удобным образом. Все, что я делаю, это писать над <iframe> объект документа с новым, созданным с нуля. Это позволяет мне просто включать <script> элемент в строке, которую я затем записываю в <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>

Я надеюсь, что это поможет кому-то по дороге!

Ответ 3

Ответ на исходный вопрос прост - выполнение script выполняется с помощью jquery, и поскольку jquery загружается в верхний фрейм, здесь также запускается script, независимо от того, где вы добавляете Это. Более разумная реализация jquery, без сомнения, может быть использована для использования правильного объекта window, но на данный момент все так, как они.

Что касается обходных решений, у вас уже есть два хороших ответа (даже если вы сами). Я могу добавить, что вы можете использовать одно из этих обходных решений, чтобы включить jquery.js в iframe, а затем получить этот объект jquery вместо верхнего, чтобы вставить дополнительную разметку... но это тоже может быть слишком велико.