Comment rendre un iframe réactif, sans assumer un rapport d'aspect? Par exemple, le contenu peut avoir une largeur ou une hauteur inconnue avant le rendu.
Remarque, vous pouvez utiliser Javascript.
Exemple:
<div id="iframe-container">
<iframe/>
</div>
Dimensionnez-le de telle iframe-container
sorte que son contenu rentre à peine à l'intérieur sans espace supplémentaire, en d'autres termes, il y a suffisamment d'espace pour le contenu afin qu'il puisse être affiché sans défilement, mais sans excès d'espace. Le conteneur enveloppe parfaitement l'iframe.
Cela montre comment rendre un iframe réactif, en supposant que le rapport d'aspect du contenu est de 16: 9. Mais dans cette question, le rapport d'aspect est variable.
Réponses:
Il n'est pas possible d'interagir avec une iFrame d'origine différente en utilisant Javascript afin d'en obtenir la taille; la seule façon de le faire est d'utiliser
window.postMessage
avec l'targetOrigin
ensemble de votre domaine ou le caractère générique*
de la source iFrame. Vous pouvez proxy le contenu des différents sites d'origine et utilisersrcdoc
, mais cela est considéré comme un hack et cela ne fonctionnera pas avec les SPA et de nombreuses autres pages plus dynamiques.Même taille iFrame d'origine
Supposons que nous ayons deux mêmes iFrames d'origine, une de courte hauteur et de largeur fixe:
et un iFrame de grande hauteur:
Nous pouvons obtenir la taille d'iFrame sur l'
load
événement en utilisant ceiframe.contentWindow.document
que nous enverrons à la fenêtre parent en utilisantpostMessage
:Nous obtiendrons la largeur et la hauteur appropriées pour les deux iFrames; vous pouvez le vérifier en ligne ici et voir la capture d'écran ici .
Taille différente iFrame origine bidouille ( non recommandé )
La méthode décrite ici est un hack et elle doit être utilisée si c'est absolument nécessaire et qu'il n'y a pas d'autre moyen de contourner; cela ne fonctionnera pas pour la plupart des pages et des SPA générés dynamiquement. La méthode récupère le code source HTML de la page à l'aide d'un proxy pour contourner la stratégie CORS (
cors-anywhere
est un moyen facile de créer un serveur proxy CORS simple et il a une démo en lignehttps://cors-anywhere.herokuapp.com
), puis il injecte du code JS dans ce HTML pour utiliserpostMessage
et envoyer la taille du iFrame vers le document parent. Il gère même l' événement iFrameresize
( combiné avec iFramewidth: 100%
) et publie la taille de l'iFrame au parent.patchIframeHtml
:Une fonction pour patcher le code HTML iFrame et injecter du Javascript personnalisé qui utilisera
postMessage
pour envoyer la taille iFrame au parent encoreload
et encoreresize
. S'il y a une valeur pour leorigin
paramètre, alors un<base/>
élément HTML sera ajouté à la tête en utilisant cette URL d'origine, ainsi, les URI HTML comme/some/resource/file.ext
seront récupérés correctement par l'URL d'origine à l'intérieur de l'iFrame.getIframeHtml
:Une fonction pour obtenir une page HTML contournant le CORS à l'aide d'un proxy si
useProxy
param est défini. Il peut y avoir des paramètres supplémentaires qui seront transmis àpostMessage
lors de l'envoi des données de taille.La fonction de gestionnaire d'événements de message est exactement la même que dans "Taille d'origine iFrame" .
Nous pouvons maintenant charger un domaine d'origine croisée à l'intérieur d'un iFrame avec notre code JS personnalisé injecté:
Et nous obtiendrons l'iFrame à la taille de son contenu sur toute sa hauteur sans aucun défilement vertical, même en utilisant
overflow-y: auto
le corps de l'iFrame ( il devrait en êtreoverflow-y: hidden
ainsi afin que la barre de défilement ne scintille pas lors du redimensionnement ).Vous pouvez le vérifier en ligne ici .
Encore une fois pour remarquer que c'est un hack et qu'il faut l'éviter ; nous ne pouvons pas accéder au document Cross-Origin iFrame ni injecter aucune sorte de choses.
la source
cors-anywhere
est en panne pour le moment, vous ne pouvez donc pas voir la page de démonstration . Je ne veux pas ajouter de capture d'écran du site externe pour des raisons de copyright. J'ajouterai un autre proxy CORS s'il reste en panne longtemps.Il y a beaucoup de complications avec la détermination de la taille du contenu dans un iframe, principalement en raison du CSS qui vous permet de faire des choses qui peuvent casser la façon dont vous mesurez la taille du contenu.
J'ai écrit une bibliothèque qui s'occupe de toutes ces choses et qui fonctionne également entre domaines, vous pourriez trouver cela utile.
https://github.com/davidjbradshaw/iframe-resizer
la source
Ma solution est sur GitHub et JSFiddle .
Présentation d'une solution pour un iframe réactif sans hypothèse de rapport d'aspect.
NB: N'oubliez pas d'appeler la fonction resize après le chargement de la page car la fenêtre n'est pas redimensionnée d'elle-même après le chargement de la page.
Le code
index.html
style.css
main.js
J'ai passé un peu de temps là-dessus. J'espère que vous l'apprécierez =)
Modifier C'est probablement la meilleure solution générique. Cependant, lorsqu'il est très petit, l'iframe n'a pas la bonne taille. Ceci est spécifique à l'iframe que vous utilisez. Il n'est pas possible de coder une réponse appropriée à ce phénomène à moins d'avoir le code de l'iframe, car votre code n'a aucun moyen de savoir quelle taille est préférée par l'iframe pour être correctement affiché.
Seuls certains hacks comme celui présenté par @Christos Lytras peuvent faire l'affaire, mais cela ne fonctionnera jamais pour chaque iframe. Juste dans une situation particulière.
la source
Faire une chose définir un conteneur Iframe une propriété CSS de largeur et hauteur définie
la source