46 votes

Pourquoi l'ajout d'un <script> to a dynamically created <iframe> seem to run the script in the parent page?

Je suis d'essayer de créer une <iframe> à l'aide de JavaScript, puis ajoutez un élément <script> à <iframe>, que je tiens à exécuter dans le contexte de l' <iframe>d document.

Malheureusement, il semble que je suis en train de faire quelque chose de mal - mon JavaScript semble s'exécuter, mais le contexte de l' <script> est le parent de la page, pas le <iframe>d document. J'ai aussi une 301 Erreur dans Firebug de l'onglet "Net" lorsque le navigateur demande iframe_test.js, mais il demande ensuite à nouveau (je ne sais pas pourquoi?) avec succès.

C'est le code que j'utilise (démonstration en direct à 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);
});

Une chose qui semble inhabituel, c'est que le code dans iframe_test.js fonctionne même; je n'ai pas de chargement de jQuery dans les <iframe> lui-même, uniquement dans le document parent. Cela semble être une idée à moi, mais je ne peux pas comprendre ce que ça signifie.

Des idées, des suggestions, etc. serait bien apprécié!

72voto

Oleg Grishko Points 1975

Avait le même problème, m'a pris des heures pour trouver la solution. Il vous suffit de créer l'objet du script à l'aide du document 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);
 

Fonctionne comme un charme!

16voto

Bungle Points 3836

Je n'ai pas trouver de réponse à ma question d'origine, mais j'ai trouvé une autre méthode qui fonctionne encore mieux (au moins pour ma part).

Ce n'utilise pas jQuery sur la page parent (qui est en fait une bonne chose, car je préfère ne pas le charger là), mais il n'chargement de jQuery dans les <iframe>, apparemment tout à fait valable et utilisable. Tout ce que je fais, c'est écrit sur le <iframe>'s d'objet de document avec un nouveau créé à partir de zéro. Cela me permet de simplement inclure un élément <script> dans une chaîne de caractères qui je puis écrire les <iframe>'s de l'objet document.

Le 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>

J'espère que cela aide quelqu'un en bas de la route!

0voto

Nickolay Points 14384

Je n’ai pas le temps de procéder au débogage complet, mais j’aperçois rapidement que jquery est en train d’agir:

 document.documentElement.innerHTML
// gives the document source without the <script src>

document.documentElement.
  getElementsByTagName("iframe")[0].contentDocument.documentElement.innerHTML

// gives: <head><title></title></head><body></body>
 

Une question très intéressante, merci!

0voto

user2107721 Points 1

La réponse à la question de départ est simple: l'exécution du script est fait en jquery, et depuis jquery est chargé dans le cadre du haut, c'est là que le script s'exécute trop, n'importe où vous êtes ajoutant. Un plus intelligente de la mise en œuvre de jquery peut sans doute être fait pour utiliser la bonne fenêtre de l'objet, mais pour l'instant les choses sont comment ils sont.

Comme pour les solutions de contournement, vous avez déjà deux bonnes réponses (même si un seul est votre propre). Ce que je pourrais ajouter, c'est que vous pouvez utiliser l'une de ces solutions de contournement pour inclure jquery.js dans l'iframe, et puis obtenir que l'objet jquery à la place de celle d'en haut à insérer une annotation supplémentaire... mais qui peut très bien être exagéré aussi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X