web-dev-qa-db-fra.com

faire en sorte que iframe height soit dynamique en fonction du contenu contenu dans JQUERY/Javascript

Je charge une page Web aspx dans une iframe. Le contenu de l'iframe peut avoir une hauteur supérieure à celle de l'iframe. L'iframe ne devrait pas avoir de barres de défilement.

J'ai une balise wrapper div à l'intérieur de l'iframe, qui contient tout le contenu. J'ai écrit quelques jQuery pour que le redimensionnement se réalise:

$("#TB_window", window.parent.document).height($("body").height() + 50);

TB_window est le div dans lequel la Iframe est contenue.

body - la balise body de l'aspx dans l'iframe.

Ce script est attaché au contenu iframe. Je reçois l'élément TB_window de la page parente. Bien que cela fonctionne bien sur Chrome, mais le TB_window s'effondre dans Firefox. Je suis vraiment confus/perdu sur pourquoi cela se produit.

169
karry

Vous pouvez récupérer la hauteur du contenu de la IFRAME en utilisant: contentWindow.document.body.scrollHeight

Une fois la IFRAME chargée, vous pouvez modifier la hauteur en procédant comme suit:

<script type="text/javascript">
  function iframeLoaded() {
      var iFrameID = document.getElementById('idIframe');
      if(iFrameID) {
            // here you can make the height, I delete it first, then I make it again
            iFrameID.height = "";
            iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
      }   
  }
</script>   

Ensuite, sur la balise IFRAME, vous raccordez le gestionnaire comme suit:

<iframe id="idIframe" onload="iframeLoaded()" ...

Il y a quelque temps, j'ai eu besoin d'appeler iframeLoaded à partir de la IFRAME elle-même après la soumission d'un formulaire dans. Pour ce faire, procédez comme suit dans les scripts de contenu de la variable IFRAME:

parent.iframeLoaded();
190
Aristos

Une réponse légèrement améliorée à Aristos ...

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
  }
</script>  

Puis déclarez dans votre iframe comme suit:

<iframe onload="resizeIframe(this)" ...

Il y a deux améliorations mineures:

  1. Vous n'avez pas besoin d'obtenir l'élément via document.getElementById, car vous l'avez déjà dans le rappel onload.
  2. Il n'est pas nécessaire de définir le iframe.height = "" si vous souhaitez le réaffecter dans la déclaration suivante. Cela engendre des frais généraux lorsque vous utilisez un élément DOM.
93
BlueFish

J'ai trouvé que la réponse acceptée ne suffisait pas, car X-FRAME-OPTIONS: Allow-From n'est pas pris en charge par safari ou chrome . Nous sommes allés avec une approche différente à la place, trouvée dans une présentation donnée par Ben Vinagar de Disqus. L'idée est d'ajouter un écouteur d'événement à la fenêtre parente, puis à l'intérieur de l'iframe, utilisez window.postMessage pour envoyer un événement au parent lui demandant de faire quelque chose (redimensionner l'iframe).

Donc, dans le document parent, ajoutez un écouteur d'événement:

window.addEventListener('message', function(e) {
  var $iframe = jQuery("#myIframe");
  var eventName = e.data[0];
  var data = e.data[1];
  switch(eventName) {
    case 'setHeight':
      $iframe.height(data);
      break;
  }
}, false);

Et à l'intérieur de l'iframe, écrivez une fonction pour poster le message:

function resize() {
  var height = document.getElementsByTagName("html")[0].scrollHeight;
  window.parent.postMessage(["setHeight", height], "*"); 
}

Enfin, dans l'iframe, ajoutez un onLoad à la balise body pour activer la fonction de redimensionnement:

<body onLoad="resize();">
50
Marty Mulligan

Ajoutez ceci à l'iframe, cela a fonctionné pour moi:

onload="this.height=this.contentWindow.document.body.scrollHeight;"

Et si vous utilisez jQuery, essayez ce code:

onload="$(this).height($(this.contentWindow.document.body).find(\'div\').first().height());"
9
Mohit Aneja

Vous pouvez consulter quatre propriétés différentes pour obtenir la hauteur du contenu dans un iFrame.

document.documentElement.scrollHeight
document.documentElement.offsetHeight
document.body.scrollHeight
document.body.offsetHeight

Malheureusement, ils peuvent tous donner des réponses différentes et celles-ci sont inconsistantes entre les navigateurs. Si vous définissez la marge du corps sur 0, le document.body.offsetHeight donne la meilleure réponse. Pour obtenir la valeur correcte, essayez cette fonction. qui provient de la bibliothèque iframe-resizer qui permet également de conserver la taille correcte d'iFrame lorsque le contenu change ou que le navigateur est redimensionné.

function getIFrameHeight(){
    function getComputedBodyStyle(prop) {
        function getPixelValue(value) {
            var PIXEL = /^\d+(px)?$/i;

            if (PIXEL.test(value)) {
                return parseInt(value,base);
            }

            var 
                style = el.style.left,
                runtimeStyle = el.runtimeStyle.left;

            el.runtimeStyle.left = el.currentStyle.left;
            el.style.left = value || 0;
            value = el.style.pixelLeft;
            el.style.left = style;
            el.runtimeStyle.left = runtimeStyle;

            return value;
        }

        var 
            el = document.body,
            retVal = 0;

        if (document.defaultView && document.defaultView.getComputedStyle) {
            retVal =  document.defaultView.getComputedStyle(el, null)[prop];
        } else {//IE8 & below
            retVal =  getPixelValue(el.currentStyle[prop]);
        } 

        return parseInt(retVal,10);
    }

    return document.body.offsetHeight +
        getComputedBodyStyle('marginTop') +
        getComputedBodyStyle('marginBottom');
}
5
David Bradshaw

Juste au cas où cela aiderait quelqu'un. J'essayais de me tirer les cheveux en essayant de faire fonctionner ça, puis j'ai remarqué que l'iframe avait une entrée de classe avec une hauteur: 100%. Quand j'ai enlevé ceci, tout a fonctionné comme prévu. Alors, s'il vous plaît vérifier tous les conflits CSS.

2
user8640976

Vous pouvez vous référer à la question connexe ici - Comment faire en sorte que la largeur et la hauteur d’iframe soient identiques à celles de son div parent?

Pour définir la hauteur dynamique -

  1. Nous devons communiquer avec les iFrames interdomaines et les parents
  2. Ensuite, nous pouvons envoyer la hauteur de défilement/hauteur de contenu d'iframe à la fenêtre parente

Et les codes - https://Gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8

1
Mohan Dere

Plutôt que d’utiliser javscript/jquery, la méthode la plus simple que j’ai trouvée est la suivante: 

<iframe style="min-height:98vh" src="http://yourdomain.com" width="100%"></iframe>

Ici 1vh = 1% de la hauteur de la fenêtre du navigateur. La valeur théorique de la hauteur à définir est donc 100vh, mais pratiquement 98vh ont fait la magie.

1
PHP-Binod

Pour ajouter à la partie de la fenêtre qui semble être coupée en bas, surtout quand vous n'avez pas de défilement, j'ai utilisé:

function resizeIframe(iframe) {
    var addHeight = 20; //or whatever size is being cut off
    iframe.height = iframe.contentWindow.document.body.scrollHeight + addHeight + "px";
  }
0
Matt Stacey

Une réponse légèrement améliorée à BlueFish ...

function resizeIframe(iframe) {
    var padding = 50;
    if (iframe.contentWindow.document.body.scrollHeight < (window.innerHeight - padding))
        iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    else
        iframe.height = (window.innerHeight - padding) + "px";
}

Ceci prend en considération la hauteur de l'écran de Windows (navigateur, téléphone), ce qui est bon pour un design réactif et les iframes qui ont une hauteur énorme . . 

0
Tadej Vengust

La solution simple consiste à mesurer la largeur et la hauteur de la zone de contenu, puis à utiliser ces mesures pour calculer le pourcentage de remplissage inférieur.

Dans ce cas, les mesures sont 1680 x 720 px, donc le remplissage sur le fond est 720/1680 = 0.43 * 100, ce qui donne 43%.

.canvas-container {    
    position: relative;
    padding-bottom: 43%; // (720 ÷ 1680 = 0.4286 = 43%)
    height: 0;
    overflow: hidden;   
}

.canvas-container iframe {    
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;   
}
0
loek

J'ai trouvé la réponse de Troy n'a pas fonctionné. C'est le même code retravaillé pour ajax:

$.ajax({                                      
    url: 'data.php',    
    dataType: 'json',                             

    success: function(data)
    {
        // Put the data onto the page

        // Resize the iframe
        var iframe = $(window.top.document).find("#iframe");
        iframe.height( iframe[0].contentDocument.body.scrollHeight+'px' );
    }
});
0
Martin Lester

vous pouvez également ajouter une requêteAnimationFrame répétitive à votre image resizeIrame (par exemple, à partir de la réponse de @ BlueFish) qui sera toujours appelée avant que le navigateur ne peint la présentation et vous pouvez mettre à jour la hauteur de l'iframe lorsque son contenu a changé de hauteur. par exemple. formulaires de saisie, contenu chargé paresseux, etc.

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    window.requestAnimationFrame(() => resizeIframe(iframe));
  }
</script>  

<iframe onload="resizeIframe(this)" ...

votre rappel devrait être assez rapide pour n'avoir aucun impact important sur votre performance globale

0
user2520818
jQuery('.home_vidio_img1 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery(this).replaceWith(video);
});

jQuery('.home_vidio_img2 img').click(function(){
    video = <iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>;
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img3 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img4 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});
0
Keyur Savsani

Celui-ci est utile lorsque vous avez besoin d’une solution sans jquery. Dans ce cas, vous devriez essayer d'ajouter un conteneur et lui attribuer un remplissage en pourcentage.

Exemple de code HTML:

<div class="iframecontainer">
    <iframe scrolling="no" src="..." class="iframeclass"width="999px" height="618px"></iframe>
</div>

Exemple de code CSS:

.iframeclass{
    position: absolute;
    top: 0;
    width: 100%;
}

.iframecontainer{
    position: relative;
    width: 100%;
    height: auto;
    padding-top: 61%;
}
0
Juan M

Les autres réponses ne fonctionnaient pas pour moi alors j'ai fait quelques changements. J'espère que cela aidera

$('#iframe').on("load", function() {
    var iframe = $(window.top.document).find("#iframe");
    iframe.height(iframe[0].ownerDocument.body.scrollHeight+'px' );
});
0
Ravi

Échantillon utilisant PHP htmlspecialchars () + vérifie si la hauteur existe et est> 0:

$my_html_markup = ''; // Insert here HTML markup with CSS, JS... '<html><head></head><body>...</body></html>'
$iframe = '<iframe onload="if(this.contentWindow.document.body.scrollHeight) {this.height = this.contentWindow.document.body.scrollHeight;}" width="100%" src="javascript: \''. htmlspecialchars($my_html_markup) . '\'"></iframe>';
0
jteks