web-dev-qa-db-fra.com

jquery obtient la hauteur du contenu iframe une fois chargé

J'ai une page d'aide, help.php, que je charge dans un iframe dans main.phpComment puis-je obtenir la hauteur de cette page une fois qu'elle a été chargée dans l'iframe?

Je demande cela parce que je ne peux pas définir la hauteur de iframe à 100% ou automatique. C'est pourquoi je pense que j'ai besoin d'utiliser javascript .. J'utilise jQuery

CSS:

body {
    margin: 0;
    padding: 0;
}
.container {
    width: 900px;
    height: 100%;
    margin: 0 auto;
    background: silver;
}
.help-div {
    display: none;
    width: 850px;
    height: 100%;
    position: absolute;
    top: 100px;
    background: orange;
}
#help-frame {
    width: 100%;
    height: auto;
    margin:0;
    padding:0;
}

JS:

$(document).ready(function () {
    $("a.open-help").click(function () {
        $(".help-div").show();
        return false;
    })
})

HTML:

<div class='container'>
    <!-- -->
    <div class='help-div'>
        <p>This is a div with an iframe loading the help page</p>
        <iframe id="help-frame" src="../help.php" width="100%" height="100%" frameborder="1"></iframe>
    </div>  <a class="open-help" href="#">open Help in iFrame</a>

    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
</div>
70
FFish

ok j'ai enfin trouvé une bonne solution:

$('iframe').load(function() {
    this.style.height =
    this.contentWindow.document.body.offsetHeight + 'px';
});

Certains navigateurs (Safari et Opera plus anciens) indiquant que la charge est terminée avant le rendu CSS, vous devez définir un micro Timeout, vider et réassigner le code src de l'iframe. 

$('iframe').load(function() {
    setTimeout(iResize, 50);
    // Safari and Opera need a kick-start.
    var iSource = document.getElementById('your-iframe-id').src;
    document.getElementById('your-iframe-id').src = '';
    document.getElementById('your-iframe-id').src = iSource;
});
function iResize() {
    document.getElementById('your-iframe-id').style.height = 
    document.getElementById('your-iframe-id').contentWindow.document.body.offsetHeight + 'px';
}
94
FFish

La réponse la moins compliquée consiste à utiliser .contents() pour accéder à l'iframe. Fait intéressant, cependant, il retourne une valeur différente de ce que je reçois en utilisant le code dans ma réponse initiale, en raison du remplissage sur le corps, je crois. 

$('iframe').contents().height() + 'is the height'

C'est comme cela que je l'ai fait pour la communication entre domaines. Je crains donc que ce ne soit peut-être inutilement compliqué. Premièrement, je mettrais jQuery dans le document iFrame; cela consommera plus de mémoire, mais cela ne devrait pas augmenter le temps de chargement car le script ne doit être chargé qu'une seule fois. 

Utilisez jQuery de l'iFrame pour mesurer la hauteur du corps de votre iframe le plus tôt possible (onDOMReady), puis définissez le hachage de l'URL sur cette hauteur. Et dans le document parent, ajoutez un événement onload à la balise iFrame qui examinera l'emplacement de l'iframe et extraira la valeur dont vous avez besoin. Comme onDOMReady se produira toujours avant l'événement de chargement du document, vous pouvez être à peu près certain que la valeur sera communiquée correctement sans qu'une condition de concurrence critique ne complique les choses.

En d'autres termes:

... dans Help.php:

var getDocumentHeight = function() {
    if (location.hash === '') { // EDIT: this should prevent the retriggering of onDOMReady
        location.hash = $('body').height(); 
        // at this point the document address will be something like help.php#1552
    }
};
$(getDocumentHeight);

... et dans le document parent:

var getIFrameHeight = function() {
    var iFrame = $('iframe')[0]; // this will return the DOM element
    var strHash = iFrame.contentDocument.location.hash;
    alert(strHash); // will return something like '#1552'
};
$('iframe').bind('load', getIFrameHeight );
44
Andrew

J'ai trouvé ce qui suit fonctionner sur Chrome, Firefox et IE11:

$('iframe').load(function () {
    $('iframe').height($('iframe').contents().height());
});

Une fois le contenu Iframes terminé, l'événement se déclenche et la hauteur IFrames est définie sur celle de son contenu. Cela ne fonctionnera que pour les pages du même domaine que celui de l'IFrame.

19
Jack Zach Tibbles

Le code pour faire cela sans jQuery est trivial de nos jours:

const frame = document.querySelector('iframe')
function syncHeight() {
  this.style.height = `${this.contentWindow.document.body.offsetHeight}px`
}
frame.addEventListener('load', syncHeight)

Pour décrocher l'événement:

frame.removeEventListener('load', syncHeight)
5
cchamberlain

Vous n'avez pas besoin de jquery dans l'iframe pour le faire, mais je l'utilise parce que le code est tellement plus simple ...

Mettez ceci dans le document à l'intérieur de votre iframe.

$(document).ready(function() {
  parent.set_size(this.body.offsetHeight + 5 + "px");  
});

ajouté cinq ci-dessus pour éliminer la barre de défilement sur les petites fenêtres, elle n’est jamais parfaite en taille.

Et cela dans votre document parent.

function set_size(ht)
{
$("#iframeId").css('height',ht);
}
5
RkaneKnight

simple one-liner commence par une hauteur minimum par défaut et augmente jusqu'à la taille du contenu.

<iframe src="http://url.html" onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));' style="height:200px;width:100%;border:none;overflow:hidden;"></iframe>
2
Pixelomo

c'est la bonne réponse qui a fonctionné pour moi

$(document).ready(function () {
        function resizeIframe() {
            if ($('iframe').contents().find('html').height() > 100) {
                $('iframe').height(($('iframe').contents().find('html').height()) + 'px')
            } else {
                setTimeout(function (e) {
                    resizeIframe();
                }, 50);
            }
        }
        resizeIframe();
    });
1
Javier Gordo

La fonction $('iframe').load de la réponse acceptée générera désormais une erreur a.indexOf is not a function. Peut être mis à jour pour:

$('iframe').on('load', function() {
  // ...
});

Quelques autres similaires à .load obsolète depuis jQuery 1.8: "Uncaught TypeError: a.indexOf n'est pas une fonction" erreur lors de l'ouverture d'un nouveau projet de fondation

0
Ryan J. Stout