2010-10-02 4 views
66

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

Je pose cette question parce que je ne peux pas définir la hauteur de iframe à 100% ou automatique. Voilà pourquoi je pense que je dois 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> 
+0

est le contenu de l'iFrame provient-il du même domaine que la page dans laquelle il se trouve? – Andrew

+0

oui c'est andrew, je veux utiliser un iFrame car j'utilise des ancres dans la page d'aide – FFish

Répondre

90

ok j'ai finalement trouvé une bonne solution :

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

Parce que certains sourcils sers (anciennement Safari et Opera) signale le chargement terminé avant que CSS ne vous rende nécessaire pour définir un délai d'attente de micro et vider et réaffecter le 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'; 
} 
+0

cette solution fonctionne très bien comme ci-dessus obtient juste la taille des iframes cocntent dans le conteneur alors que cela obtient la taille 'real' – rickyduck

+102

cela fonctionne uniquement avec des pages sur le même domaine –

+1

Je crois que l'événement de charge déclenche sur la même boucle d'événement donc un setTimout de 1 milliseconde fonctionnera tout aussi bien –

41

Le moins compliqué la réponse est d'utiliser .contents() pour accéder à l'iframe. Fait intéressant, cependant, il renvoie une valeur différente de ce que j'obtiens en utilisant le code dans ma réponse originale, en raison du rembourrage sur le corps, je crois.

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

Voilà comment je l'ai fait pour la communication inter-domaines, alors je crains que c'est peut-être inutilement compliqué. D'abord, je mettrais jQuery dans le document de l'iFrame; cela consommera plus de mémoire, mais cela ne devrait pas augmenter le temps de chargement car le script n'a besoin d'être chargé qu'une seule fois. Utilisez la jQuery de l'iFrame pour mesurer la hauteur du corps de votre iframe le plus tôt possible (onDOMReady), puis définissez le hash d'URL à 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 certain que la valeur sera communiquée correctement sans qu'une condition de concurrence 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); 
+0

Salut Andrew jusqu'ici très bonne aide ici. contents() fonctionne très bien, mais j'ai encore besoin de le tester avec un throttler de bande passante. Peut-être que vous pouvez utiliser la propriété innerHeight(). J'ai un problème dans FF (OSX) en utilisant votre solution en mettant la hauteur dans le hachage. FF semble continuer à charger la fonction getDocumentHeight() dans une boucle infinitive? Safari est bien .. – FFish

+0

Intéressant. J'ai ajouté une vérification qui empêche le réglage du hachage s'il y a déjà une valeur. Vous devrez peut-être modifier ceci si vous chargez Help.php avec une valeur de hachage (par exemple '