web-dev-qa-db-fra.com

Ajustez la largeur et la hauteur de l'iframe en fonction de son contenu

J'ai besoin d'une solution pour ajuster automatiquement la width et height d'une iframe à peine cadrer avec son contenu. Le fait est que la largeur et la hauteur peuvent être modifiées après le chargement de la iframe. Je suppose que j'ai besoin d'une action d'événement pour gérer le changement de dimensions du corps contenu dans l'iframe.

249
StoneHeart
<script type="application/javascript">

function resizeIFrameToFitContent( iFrame ) {

    iFrame.width  = iFrame.contentWindow.document.body.scrollWidth;
    iFrame.height = iFrame.contentWindow.document.body.scrollHeight;
}

window.addEventListener('DOMContentLoaded', function(e) {

    var iFrame = document.getElementById( 'iFrame1' );
    resizeIFrameToFitContent( iFrame );

    // or, to resize all iframes:
    var iframes = document.querySelectorAll("iframe");
    for( var i = 0; i < iframes.length; i++) {
        resizeIFrameToFitContent( iframes[i] );
    }
} );

</script>

<iframe src="usagelogs/default.aspx" id="iFrame1"></iframe>
249
Ahmy

Cross-browser plug-in jQuery .

Cross-bowser, cross domain bibliothèque qui utilise mutationObserver pour conserver la taille de iFrame au contenu et postMessage pour communiquer entre la page iFrame et l'hôte. Fonctionne avec ou sans jQuery.

43
FFish

Toutes les solutions données jusqu'ici ne tiennent compte que d'un redimensionnement unique. Vous indiquez que vous souhaitez pouvoir redimensionner l'iFrame une fois le contenu modifié. Pour ce faire, vous devez exécuter une fonction dans iFrame (une fois le contenu modifié, vous devez déclencher un événement pour indiquer que le contenu a été modifié).

Je suis resté coincé avec cela pendant un moment, car le code dans l'iFrame semblait limité au DOM de l'iFrame (et ne pouvait pas éditer l'iFrame), et le code exécuté en dehors de l'iFrame était bloqué avec le DOM en dehors de l'iFrame (et ne pouvait pas t ramasser un événement venant de l’intérieur de l’iFrame).

La solution est venue en découvrant (avec l'aide d'un collègue) qu'il était possible de dire à jQuery quel DOM utiliser. Dans ce cas, le DOM de la fenêtre parente.

En tant que tel, un code tel que celui-ci fait ce dont vous avez besoin (lorsqu'il est exécuté dans l'iFrame):

<script type="text/javascript">
    jQuery(document).ready(function () {
        jQuery("#IDofControlFiringResizeEvent").click(function () {
            var frame = $('#IDofiframeInMainWindow', window.parent.document);
            var height = jQuery("#IDofContainerInsideiFrame").height();
            frame.height(height + 15);
        });
    });
</script>
32
Garnaph

Si le contenu d'iframe provient du même domaine, cela devrait fonctionner parfaitement. Cela nécessite cependant jQuery.

$('#iframe_id').load(function () {
    $(this).height($(this).contents().height());
    $(this).width($(this).contents().width());
});

Pour le redimensionner dynamiquement, vous pouvez faire ceci:

<script language="javaScript">
<!--
function autoResize(){
    $('#themeframe').height($('#themeframe').contents().height());
}
//-->
</script>
<iframe id="themeframe" onLoad="autoResize();" marginheight="0" frameborder="0" src="URL"></iframe>

Ensuite, sur la page chargée par l'iframe, ajoutez ceci:

<script language="javaScript">
function resize()
{
    window.parent.autoResize();
}

$(window).on('resize', resize);
</script>
21
brenjt

Voici une solution multi-navigateur si vous ne souhaitez pas utiliser jQuery:

/**
 * Resizes the given iFrame width so it fits its content
 * @param e The iframe to resize
 */
function resizeIframeWidth(e){
    // Set width of iframe according to its content
    if (e.Document && e.Document.body.scrollWidth) //ie5+ syntax
        e.width = e.contentWindow.document.body.scrollWidth;
    else if (e.contentDocument && e.contentDocument.body.scrollWidth) //ns6+ & opera syntax
        e.width = e.contentDocument.body.scrollWidth + 35;
    else (e.contentDocument && e.contentDocument.body.offsetWidth) //standards compliant syntax – ie8
        e.width = e.contentDocument.body.offsetWidth + 35;
}
15
Timo

J'utilise ce code pour ajuster automatiquement la hauteur de tous les iframes (avec la classe autoHeight) lorsqu'ils se chargent sur la page. Testé et cela fonctionne dans IE, FF, Chrome, Safari et Opera.

function doIframe() {
    var $iframes = $("iframe.autoHeight"); 
    $iframes.each(function() {
        var iframe = this;
        $(iframe).load(function() {
            setHeight(iframe);
        });
    });
}

function setHeight(e) {
  e.height = e.contentWindow.document.body.scrollHeight + 35;
}

$(window).load(function() {
    doIframe();
});
8
petriq

Après avoir tout essayé sur la terre, cela fonctionne vraiment pour moi.

index.html

<style type="text/css">
html, body{
  width:100%;
  height:100%;
  overflow:hidden;
  margin:0px;   
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
function autoResize(iframe) {
    $(iframe).height($(iframe).contents().find('html').height());
}
</script>

<iframe src="http://iframe.domain.com" width="100%" height="100%" marginheight="0" frameborder="0" border="0" scrolling="auto" onload="autoResize(this);"></iframe>
6
Adrian P.

Voici plusieurs méthodes:

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;height:100%;width:100%" height="100%" width="100%"></iframe>
</body>

ET UNE AUTRE ALTERNATIVE

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px" height="100%" width="100%"></iframe>
</body>

CACHEZ LE DÉFILEMENT AVEC 2 ALTERNATIVES COMME INDIQUÉ

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;height:150%;width:150%" height="150%" width="150%"></iframe>
</body>

HACK AVEC SECOND CODE

<body style="margin:0px;padding:0px;overflow:hidden">
    <iframe src="http://www.example.com" frameborder="0" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:150%;width:150%;position:absolute;top:0px;left:0px;right:0px;bottom:0px" height="150%" width="150%"></iframe>
</body>

Pour masquer les barres de défilement de l'iFrame, le parent se fait "débordement: masqué" pour masquer les barres de défilement et l'iFrame doit atteindre 150% en largeur et en hauteur, ce qui force les barres de défilement à l'extérieur de la page t ont des barres de défilement, on ne peut pas s’attendre à ce que l’iframe dépasse les limites de la page. Cela cache les barres de défilement de l'iFrame en pleine largeur!

source: set iframe auto height

4
T.Todua

C'est une solution solide

function resizer(id)
{

var doc=document.getElementById(id).contentWindow.document;
var body_ = doc.body, html_ = doc.documentElement;

var height = Math.max( body_.scrollHeight, body_.offsetHeight, html_.clientHeight, html_.scrollHeight, html_.offsetHeight );
var width  = Math.max( body_.scrollWidth, body_.offsetWidth, html_.clientWidth, html_.scrollWidth, html_.offsetWidth );

document.getElementById(id).style.height=height;
document.getElementById(id).style.width=width;

}

le html

<IFRAME SRC="blah.php" id="iframe1"  onLoad="resizer('iframe1');"></iframe>
4
Mas

J'ai légèrement modifié la bonne solution de Garnaph ci-dessus. Il semblait que sa solution modifiait la taille de l’iframe en fonction de la taille juste avant l’événement. Pour ma situation (envoi d'email via un iframe), j'avais besoin de la hauteur d'iframe pour changer juste après l'envoi. Par exemple, affichez les erreurs de validation ou le message "merci" après la soumission. 

Je viens d'éliminer la fonction click () imbriquée et de la mettre dans mon iframe html:

<script type="text/javascript">
    jQuery(document).ready(function () {
        var frame = $('#IDofiframeInMainWindow', window.parent.document);
        var height = jQuery("#IDofContainerInsideiFrame").height();
        frame.height(height + 15);
    });
</script>

Travaillé pour moi, mais pas sûr de la fonctionnalité du navigateur.

3
udackds

tous ne peuvent pas travailler en utilisant les méthodes ci-dessus.

javascript:

function resizer(id) {
        var doc = document.getElementById(id).contentWindow.document;
        var body_ = doc.body, html_ = doc.documentElement;

        var height = Math.max(body_.scrollHeight, body_.offsetHeight, html_.clientHeight, html_.scrollHeight, html_.offsetHeight);
        var width = Math.max(body_.scrollWidth, body_.offsetWidth, html_.clientWidth, html_.scrollWidth, html_.offsetWidth);

        document.getElementById(id).style.height = height;
        document.getElementById(id).style.width = width;

    }

html:

<div style="background-color:#b6ff00;min-height:768px;line-height:inherit;height:inherit;margin:0px;padding:0px;overflow:visible" id="mainDiv"  >
         <input id="txtHeight"/>height     <input id="txtWidth"/>width     
        <iframe src="head.html" name="topFrame" scrolling="No" noresize="noresize" id="topFrame" title="topFrame" style="width:100%; height: 47px" frameborder="0"  ></iframe>
        <iframe src="left.aspx" name="leftFrame" scrolling="yes"   id="Iframe1" title="leftFrame" onload="resizer('Iframe1');" style="top:0px;left:0px;right:0px;bottom:0px;width: 30%; border:none;border-spacing:0px; justify-content:space-around;" ></iframe>
        <iframe src="index.aspx" name="mainFrame" id="Iframe2" title="mainFrame" scrolling="yes" marginheight="0" frameborder="0" style="width: 65%; height:100%; overflow:visible;overflow-x:visible;overflow-y:visible; "  onload="resizer('Iframe2');" ></iframe>
</div>

Env: IE 10, Windows 7 x64

2
Kevin

Si vous pouvez contrôler à la fois le contenu IFRAME et la fenêtre parente, vous avez besoin du iFrame Resizer .

Cette bibliothèque permet le redimensionnement automatique de la hauteur et de la largeur des images iFrames identiques et interdomaines pour s’adapter au contenu qu'elles contiennent. Il fournit toute une gamme de fonctionnalités permettant de résoudre les problèmes les plus courants liés à l'utilisation d'iFrames, notamment:

  • Redimensionnement en hauteur et en largeur de l'iFrame à la taille du contenu.
  • Fonctionne avec plusieurs et imbriqués iFrames.
  • Authentification de domaine pour les iFrames interdomaines.
  • Fournit une gamme de méthodes de calcul de taille de page pour prendre en charge des dispositions CSS complexes.
  • Détecte les modifications du DOM pouvant entraîner le redimensionnement de la page à l'aide de MutationObserver.
  • Détecte les événements pouvant entraîner le redimensionnement de la page (événements de redimensionnement de fenêtre, d'animation CSS et de transition, de changement d'orientation et de souris).
  • Messagerie simplifiée entre iFrame et la page hôte via postMessage.
  • Corrige les liens de page dans iFrame et prend en charge les liens entre iFrame et la page parent.
  • Fournit des méthodes de dimensionnement et de défilement personnalisées.
  • Expose la position parent et la taille de la fenêtre d'affichage dans l'iFrame.
  • Fonctionne avec ViewerJS pour prendre en charge les documents PDF et ODF.
  • Prise en charge de secours jusqu'à IE8.
2
stokito

J'ai trouvé une autre solution après quelques expériences. Au départ, j'ai essayé le code marqué comme "meilleure réponse" à cette question et cela n'a pas fonctionné. Mon hypothèse est que mon iframe dans mon programme à l'époque était généré dynamiquement. Voici le code que j'ai utilisé (cela a fonctionné pour moi):

Javascript dans l'iframe en cours de chargement:

window.onload = function()
    {
        parent.document.getElementById('fileUploadIframe').style.height = document.body.clientHeight+5+'px';
        parent.document.getElementById('fileUploadIframe').style.width = document.body.clientWidth+18+'px';
    };

Il est nécessaire d’ajouter 4 pixels ou plus à la hauteur pour supprimer les barres de défilement (un étrange bug/effet d’iframes). La largeur est encore plus étrange, vous pouvez ajouter 18px à la largeur du corps. Assurez-vous également que le css du corps de l'iframe est appliqué (ci-dessous).

html, body {
   margin:0;
   padding:0;
   display:table;
}

iframe {
   border:0;
   padding:0;
   margin:0;
}

Voici le code HTML pour l'iframe:

<iframe id="fileUploadIframe" src="php/upload/singleUpload.html"></iframe>

Voici tout le code dans mon iframe:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>File Upload</title>
    <style type="text/css">
    html, body {
        margin:0;
        padding:0;
        display:table;
    }
    </style>
    <script type="text/javascript">
    window.onload = function()
    {
        parent.document.getElementById('fileUploadIframe').style.height = document.body.clientHeight+5+'px';
        parent.document.getElementById('fileUploadIframe').style.width = document.body.clientWidth+18+'px';
    };
    </script>
</head>
<body>
    This is a test.<br>
    testing
</body>
</html>

J'ai fait des tests en chrome et un peu en firefox (sous windows xp). J'ai encore d'autres tests à faire, alors dites-moi comment cela fonctionne pour vous.

1
www139

J'ai trouvé ce resizer mieux fonctionner:

function resizer(id)
{

    var doc = document.getElementById(id).contentWindow.document;
    var body_ = doc.body;
    var html_ = doc.documentElement;

    var height = Math.max( body_.scrollHeight, body_.offsetHeight, html_.clientHeight,     html_.scrollHeight, html_.offsetHeight );
    var width  = Math.max( body_.scrollWidth, body_.offsetWidth, html_.clientWidth, html_.scrollWidth, html_.offsetWidth );

    document.getElementById(id).height = height;
    document.getElementById(id).width = width;

}

Notez que l'objet de style est supprimé.

1
BabaRick

Au cas où quelqu'un arriverait ici: J'ai eu un problème avec les solutions lorsque j'ai retiré les divs de l'iframe - l'iframe ne s'est pas raccourci.

Il existe un plugin Jquery qui fait le travail:

http://www.jqueryscript.net/layout/jQuery-Plugin-For-Auto-Resizing-iFrame-iFrame-Resizer.html

1
Sarah Sh

Dans jQuery, c'est la meilleure option pour moi, ça m'aide vraiment !! J'attends que ça vous aide!

iframe

<iframe src="" frameborder="0" id="iframe" width="100%"></iframe>

jQuery

<script>            
        var valueSize = $( "#iframe" ).offset();
        var totalsize = (valueSize.top * 2) + valueSize.left;

        $( "#iframe" ).height(totalsize);            

</script>
1
Kike Gamboa

Il est possible de créer un IFrame "semblable à un fantôme" qui agit comme s'il n'était pas là.

Voir http://codecopy.wordpress.com/2013/02/22/ghost-iframe-crossdomain-iframe-resize/

En gros, vous utilisez le système d'événements parent.postMessage(..) décrit dans https://developer.mozilla.org/en-US/docs/DOM/window.postMessage

Cela fonctionne sur tous les navigateurs modernes!

0
Calciol

Si le contenu est simplement un fichier HTML très simple, le moyen le plus simple consiste à supprimer l'iframe avec javascript

html:

<div class="iframe">
    <iframe src="./mypage.html" frameborder="0" onload="removeIframe(this);"></iframe>
</div>

javascript:

function removeIframe(obj)(
    var iframeDocument = obj.contentDocument || obj.contentWindow.document;
    var mycontent = iframeDocument.getElementsByTagName("body")[0].innerHTML;
    obj.remove();
    document.getElementsByClassName("iframe")[0].innerHTML = mycontent;
}
0
Daniel Katz

Le contexte

Je devais le faire moi-même dans un contexte d'extension web. Cette extension Web injecte une partie de l'interface utilisateur dans chaque page et cette interface vit dans un iframe. Le contenu de iframe étant dynamique, il a donc fallu réajuster la largeur et la hauteur de iframe lui-même.

J'utilise React mais le concept s'applique à toutes les bibliothèques.

Ma solution (cela suppose que vous contrôliez à la fois la page et l'iframe)

À l'intérieur de iframe, j'ai changé les styles body pour avoir de très grandes dimensions. Cela permettra aux éléments à l'intérieur de disposer en utilisant tout l'espace nécessaire. Rendre width et height 100% ne fonctionnait pas pour moi (je suppose parce que l'iframe a un width = 300px et un height = 150px par défaut)

/* something like this */
body {
  width: 99999px;
  height: 99999px;
}

Ensuite, j'ai injecté toute l'interface utilisateur d'iframe dans une div et lui ai donné quelques styles.

#ui-root {
  display: 'inline-block';     
}

Après avoir rendu mon application dans ce #ui-root (dans React, je le fais dans componentDidMount). Je calcule les dimensions de cette div comme et les synchronise avec la page parent à l'aide de window.postMessage:

let elRect = el.getBoundingClientRect()
window.parent.postMessage({
  type: 'resize-iframe',
  payload: {
    width: elRect.width,
    height: elRect.height
  }
}, '*')

Dans le cadre parent, je fais quelque chose comme ceci:

window.addEventListener('message', (ev) => {
  if(ev.data.type && ev.data.type === 'resize-iframe') {
    iframe.style.width = ev.data.payload.width + 'px'
    iframe.style.height = ev.data.payload.height + 'px'
  }
}, false)
0
bboydflo

C'est comme ça que je l'ai fait en charge ou quand les choses changent.

parent.jQuery("#frame").height(document.body.scrollHeight+50);
0
MrPHP

Pour l'attribut directive angularjs:

G.directive ( 'previewIframe', function () {
return {
    restrict : 'A',
    replace : true,
    scope : true,
    link : function ( scope, elem, attrs ) {
        elem.on ( 'load', function ( e ) {
            var currentH = this.contentWindow.document.body.scrollHeight;
            this.style.height = eval( currentH ) + ( (25 / 100)* eval( currentH ) ) + 'px';
        } );
    }
};
} );

Notez le pourcentage, je l'ai inséré pour que vous puissiez contrer la mise à l'échelle habituellement effectuée pour iframe, texte, annonces, etc., il suffit de mettre 0 si aucune mise à l'échelle n'est implémentée 

0

Voici comment je le ferais (testé en FF/Chrome):

<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
function autoResize(iframe) {
    $(iframe).height($(iframe).contents().find('html').height());
}
</script>

<iframe src="page.html" width="100%" height="100" marginheight="0" frameborder="0" onload="autoResize(this);"></iframe>
0
Latheesan

Javascript à placer dans l'en-tête:

function resizeIframe(obj) {
        obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
      }

Voici le code html iframe:

<iframe class="spec_iframe" seamless="seamless" frameborder="0" scrolling="no" id="iframe" onload="javascript:resizeIframe(this);" src="somepage.php" style="height: 1726px;"></iframe>

Feuille de style css

>

.spec_iframe {
        width: 100%;
        overflow: hidden;
    }
0
Alin Razvan

Clairement, il y a beaucoup de scénarios, cependant, j'avais le même domaine pour document et iframe et j'ai été en mesure de l'ajouter à la fin de mon contenu iframe:

var parentContainer = parent.document.querySelector("iframe[src*=\"" + window.location.pathname + "\"]");
parentContainer.style.height = document.body.scrollHeight + 50 + 'px';

Ceci "trouve" le conteneur parent, puis définit la longueur en ajoutant un facteur de fudge de 50 pixels pour supprimer la barre de défilement.

Il n'y a rien là-bas pour "observer" la hauteur du document qui change, ce dont je n'avais pas besoin pour mon cas d'utilisation. Dans ma réponse, j'apporte un moyen de référencer le conteneur parent sans utiliser d'identifiants intégrés dans le contenu parent/iframe.

0
Henry's Cat

Je sais que le message est ancien, mais je crois que c'est encore une autre façon de le faire. Je viens d'implémenter sur mon code. Fonctionne parfaitement au chargement et au redimensionnement de la page:

var videoHeight;
var videoWidth;
var iframeHeight;
var iframeWidth;

function resizeIframe(){
    videoHeight = $('.video-container').height();//iframe parent div's height
    videoWidth = $('.video-container').width();//iframe parent div's width

    iframeHeight = $('.youtubeFrames').height(videoHeight);//iframe's height
    iframeWidth = $('.youtubeFrames').width(videoWidth);//iframe's width
}
resizeIframe();


$(window).on('resize', function(){
    resizeIframe();
});
0
Gabriel Ferraz