Spécification du contenu d'un iframe au lieu de l'attribut src à une page

88

Je travaille actuellement sur un formulaire qui inclut des entrées de fichiers pour télécharger des images. Il y a un onchange()événement pour ces entrées qui soumet les images à un iframe, puis charge dynamiquement les images téléchargées dans le formulaire, avec des champs à modifier pour elles (comme le nom et la géolocalisation ).

Comme je ne peux pas imbriquer les formulaires, le file_inputest également contenu dans un fichier iframe. Au final, j'utilise un iframeintérieur d'un autre iframe. Alors j'ai quelque chose comme ça:

<form>
<!-- LOTS OF FIELDS!! -->
<iframe src="file_input_url">
<!-- iframe which loads a page of a form with a file input-->
</iframe>
</form>

et le HTML chargé dans le iframeest quelque chose comme (à l'exclusion des balises html, headet body)

<form target="upload_iframe">
<input type="file" onchange="this.form.submit()">
</form>
<iframe name="upload_iframe"></iframe>

Cela fonctionne très bien, à l'exception du fait qu'il faut quelques secondes pour charger le premier iframe, de sorte que l'entrée de fichier ne se charge pas avec le reste de la page. Ce n'est pas visuellement idéal. Je pourrais le résoudre si je pouvais spécifier le iframecontenu sans avoir à charger une autre page (spécifiée par file_input_urldans la première iframe).

Existe-t-il un moyen de spécifier le iframecontenu dans le même document, ou ne peut-il être spécifié qu'avec l' srcattribut, nécessitant le chargement d'une autre page?

orlox
la source
Cela ne devrait pas prendre «quelques secondes» pour charger cette iframe. Je m'attendrais à ce que ce soit plus comme un dixième de milliseconde plus le "temps de mordre" (qui devrait également être des millisecondes). Vous devriez rechercher ce qui cause tout le décalage - probablement quelque chose qui ne va pas avec votre serveur.
Abhi Beckert

Réponses:

95

Vous pouvez .write()le contenu dans le document iframe. Exemple:

<iframe id="FileFrame" src="about:blank"></iframe>

<script type="text/javascript">
   var doc = document.getElementById('FileFrame').contentWindow.document;
   doc.open();
   doc.write('<html><head><title></title></head><body>Hello world.</body></html>');
   doc.close();
</script>
Guffa
la source
1
J'avais pensé à cette possibilité, cependant, le html qui doit être chargé dans l'iframe est complexe, et le gérer entièrement en javascript pour l'écrire dans l'iframe obscurcirait trop l'implémentation (au point que je préfère le laisser tel qu'il est).
orlox
2
@orlox: récupérez votre contenu sur le serveur en utilisant Ajax et injectez-le. Si vous ne voulez pas aller dans cette direction, créez un divélément caché avec votre contenu et placez son contenu iframeentre <body>et </body>.
stackular
11
Plus j'apprends sur les restrictions iframes, plus je les déteste
John Magnolia
1
Comment échapper aux guillemets simples en utilisant cette méthode? Certains d'entre eux sont importants pour le HTML (par exemple, class = 'example'), certains sont importants pour CSS (par exemple, font-family: 'Verdana';) et certains sont contenus (par exemple, George O'Malley).
Dan Bechard
2
@Dan: Pour échapper à toute valeur à utiliser dans une chaîne JavaScript délimitée par une apostrophe, vous devez d'abord échapper les contre-obliques, puis les apostrophes. Par exemple en utilisant C # pour la sortie d' une chaîne dans le code: doc.write('<%= html.Replace("\\", "\\\\").Replace("'", "\\'") %>');.
Guffa
36

iframe prend désormais en charge srcdoc qui peut être utilisé pour spécifier le contenu HTML de la page à afficher dans le cadre en ligne.

Ayush Gupta
la source
2
IE ne prend pas en charge ce droit, mais vous pouvez vérifier caniuse pour le dernier statut à ce sujet.
Ayush Gupta
Documentation sur MDN
Benoit Blanchon
22

Vous pouvez utiliser l' data:URL dans src:

var html = 'Hello from <img src="http://stackoverflow.com/favicon.ico" alt="SO">';
var iframe = document.querySelector('iframe');
iframe.src = 'data:text/html,' + encodeURIComponent(html);
<iframe></iframe>

Différence entre srcdoc = “…” et src = “data: text / html,…” dans une iframe .

Convertir du HTML en données: lien texte / html à l'aide de JavaScript .

utilisateur
la source
1
Vous n'avez même pas besoin de JavaScript: l' srcattribut peut être spécifié en ligne s'il est échappé, par exemple en utilisant rawurlencodeen PHP:<iframe src="<?php echo htmlspecialchars('data:text/html,' . rawurlencode($content)); ?>"></iframe>
Jake
Microsoft a ajouté une prise en charge pour cela à peu près en même temps que la prise en charge srcdoc, et srcdocc'est la meilleure façon de le faire. Les URL de données ne sont largement prises en charge que pour les images et CSS - pour autant que je sache, aucune version d'Internet Explorer ne les prend en charge dans une iframe.
Abhi Beckert
6

En combinaison avec ce que Guffa a décrit, vous pouvez utiliser la technique décrite dans Explication de <script type = "text / template"> ... </script> pour stocker le document HTML dans un scriptélément spécial (voir le lien pour une explication sur comment cela fonctionne). C'est beaucoup plus facile que de stocker le document HTML dans une chaîne.

ximo
la source
Après réflexion, cela ne fonctionnerait pas très bien pour un document HTML complet. Mots - clés tels que <html>, <body>, <script>ne confondez pas seulement le navigateur, briser le rendu du document.
ximo le
Cela ne semble pas être un problème, les balises HTML à l'intérieur des scripts sont ignorées.
HBP
Vous avez raison :) Je n'avais pas encore essayé la technique quand j'ai écrit cela, et j'ai dû reprendre cette hypothèse quelque part. J'ai découvert plus tard que tout ce qui se trouve dans une <script>balise serait ignoré par le navigateur. Merci de m'avoir corrigé!
ximo le