54 votes

Inscrire des éléments dans une iframe enfant en utilisant Javascript ou jQuery

J'ai quelque chose comme ça :

<!doctype html>
<html>
  <body>
     <iframe id="someFrame"></iframe>
  </body>
</html>

Et je voudrais utiliser jQuery pour écrire des éléments de telle sorte que le HTML équivalent complet soit comme ceci :

<!doctype html>
<html>
  <body>
    <iframe id="someFrame">
      <!-- inside the iframe's content -->
      <!-- <html><body>  -->
      <div>A</div>
      <div>B</div>
      <div>C</div>
      <!-- </body></html> -->
    </iframe>
  </body>
</html>

Sinon, n'importe quel Javascript ordinaire conviendrait.

Merci.

Modifier : Après un peu plus de recherche, il semble que je cherche un équivalent IE de la propriété contentDocument d'un iframe. "contentDocument" est une norme W3C que FF supporte, mais pas IE. (surprise surprise)

95voto

Mike Robinson Points 12273

Vous pouvez faire les deux, vous devez juste cibler différemment :

var ifrm = document.getElementById('myIframe');
ifrm = ifrm.contentWindow || ifrm.contentDocument.document || ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write('Hello World!');
ifrm.document.close();

2 votes

Aha - contentWindow. En fait, j'ai trouvé que l'ouverture et la fermeture sont nécessaires pour commencer à utiliser jquery...

0 votes

Cette méthode ne fonctionne plus. Je reçois l'erreur js qui dit Unsafe JavaScript attempt to access frame with URL "URL1" from frame with URL "URL2". Les domaines, protocoles et ports doivent correspondre. L'approche par pont indiquée ci-dessous fonctionne bien.

1 votes

Je sais que c'est un vieux sujet, mais dans quel cas auriez-vous jamais ifrm.contentDocument.document.document ?

36voto

Jeff Meatball Yang Points 12021

Après quelques recherches, et une réponse corroborante de Mike, j'ai trouvé la solution suivante :

  var d = $("#someFrame")[0].contentWindow.document; // contentWindow works in IE7 and FF
  d.open(); d.close(); // must open and close document object to start using it!

  // now start doing normal jQuery:
  $("body", d).append("<div>A</div><div>B</div><div>C</div>");

13 votes

Intéressant. Savez-vous pourquoi vous devez faire l'ouverture et la fermeture ?

0 votes

C'était génial ! Merci Jeff !

0 votes

C'est une solution parfaite à un problème que j'avais avec codemirrors. editor.getValue() !

10voto

Mori Points 1044

Il existe deux méthodes fiables pour accéder au document à l'intérieur d'un élément iframe :

1. Le site fenêtres.cadres propriété :

var iframeDocument = window.frames['iframeName'].document; // or // var iframeDocument = window.frames[iframeIndex].document;

Démo

2. Le site contenuDocument propriété :

var iframeDocument = document.getElementById('iframeID').contentDocument; // or // var iframeDocument = document.getElementById('iframeID').contentWindow.document;

Démo

0 votes

Parfait, le JSFiddle a été très utile. Merci !

7voto

jlarson Points 3823

Je vais prendre des risques et suggérer que les réponses proposées jusqu'à présent ne sont pas possibles.

Si cet iframe a effectivement une src="somepage.html" (ce que vous auriez dû indiquer, et si ce n'est pas le cas, quel est l'intérêt d'utiliser iframe ?), alors je ne pense pas que Jquery puisse manipuler directement le html à travers les cadres dans tous les navigateurs. D'après mon expérience de ce genre de choses, la page qui contient le cadre ne peut pas appeler directement des fonctions à partir de la page iframe ou établir un quelconque contact Javascript avec celle-ci.

Votre "somepage.html" (la page qui se charge dans l'iframe) doit faire deux choses :

  1. Transmettez un objet à la page de référence qui peut être utilisé comme pont.
  2. Avoir une fonction pour définir le HTML comme vous le souhaitez

Ainsi, par exemple, somepage.html pourrait ressembler à ceci :

<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
    var bridge={
        setHtml:function(htm) {
            document.body.innerHTML=htm;
        }
    }

    $(function() { parent.setBridge(bridge); });

//--></script>
</head>
<body></body>
</html>

et la page d'accueil pourrait ressembler à ceci :

<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
var bridge;
var setBridge=function(br) {
    bridge=br;
    bridge.setHtml("<div>A</div><div>B</div><div>C</div>");
    }
//-->
</script>
</head>
<body><iframe src="somepage.html"></iframe></body>
</html>

Cela peut sembler un peu alambiqué mais il peut être adapté dans un certain nombre de directions et devrait fonctionner au moins dans IE, FF, Chrome, et probablement Safari et Opera...

0 votes

Merci pour votre réponse - mais je veux utiliser cette iframe pour composer du HTML comme un éditeur de texte riche. Je ne définis pas l'attribut src car il sera effacé et recomposé à partir de la fenêtre "supérieure". De plus, je pense qu'il doit être possible d'atteindre le DOM de l'enfant - voir mon édition dans le PO.

0 votes

Y a-t-il une raison pour laquelle vous devez utiliser un iframe et non un div ? Il semble que le div serait plus facile et moins susceptible d'être cassé par les navigateurs.

1 votes

Il se trouve qu'il y a une raison. Vous devez placer du javascript externe et ne voulez pas qu'il endommage votre page. Mais vous avez également besoin que le référent corresponde à votre domaine de premier niveau. C'est la méthode la plus courante pour placer des publicités sur une page : <iframe></iframe> + document.write('<scriptles balises vont ici>')

1voto

damijank Points 1

J'ai trouvé que cela était compatible avec tous les navigateurs... un peu de croisement des réponses précédentes et un peu d'essais et d'erreurs de ma part :)

Je l'utilise pour le téléchargement d'un rapport, ou, si une erreur (message) se produit, elle est affichée dans l'iFrame. La plupart des utilisateurs auront probablement caché l'iFrame, je l'utilise de manière multifonctionnelle.

Le problème est que je dois effacer le contenu de l'iFrame chaque fois que je clique sur le bouton de téléchargement du rapport - l'utilisateur peut modifier les paramètres et il arrive qu'il n'y ait pas de résultats, ce qui s'affiche alors dans l'iFrame sous forme de message. S'il y a sont le résultat est que l'iFrame reste vide - parce que le code ci-dessous l'a effacé et que l'affichage de l'iFrame a été modifié. window.open(...) génère un Content-Disposition: attachment;filename=... document.

var $frm = $("#reportIFrame");
var $doc = $frm[0].contentWindow ? $frm[0].contentWindow.document : $frm[0].contentDocument;
var $body = $($doc.body);
$body.html(''); // clear iFrame contents <- I'm using this...
$body.append('<i>Writing into the iFrame...</i>'); // use this to write something into the iFrame
window.open(Module.PATH + 'php/getReport.php' + Report.queryData, 'reportIFrame');

Je n'ai pas de navigateur qui supporte contentDocument mais je l'ai codé de cette façon donc je le laisse. Peut-être que quelqu'un a des navigateurs plus anciens et peut poster des confirmations/problèmes de compatibilité ?

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