Tengo una página de ayuda, help.php que estoy cargando dentro de un iframe en main.php. ¿Cómo puedo obtener la altura de esta página una vez que se ha cargado en el iframe?
Estoy preguntando esto porque no puedo diseñar la altura de iframe al 100% o automático. Por eso creo que necesito usar javascript ... Estoy usando 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>
Respuestas:
ok finalmente encontré una buena solución:
$('iframe').load(function() { this.style.height = this.contentWindow.document.body.offsetHeight + 'px'; });
Debido a que algunos navegadores (Safari y Opera más antiguos) informan que la carga se completó antes de que CSS se procese, debe establecer un tiempo de espera micro y dejar en blanco y reasignar el src del 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'; }
fuente
real
tamañodocument
altura, no labody
altura. Usando jQuery puedes agarrarlo con$(this.contentWindow.document).height()
.La respuesta menos complicada es usar
.contents()
para obtener el iframe. Curiosamente, sin embargo, devuelve un valor diferente del que obtengo usando el código en mi respuesta original, debido al relleno en el cuerpo, creo.$('iframe').contents().height() + 'is the height'
Así es como lo he hecho para la comunicación entre dominios, así que me temo que quizás sea innecesariamente complicado. Primero, pondría jQuery dentro del documento de iFrame; esto consumirá más memoria, pero no debería aumentar el tiempo de carga ya que el script solo necesita cargarse una vez.
Use jQuery de iFrame para medir la altura del cuerpo de su iframe lo antes posible (onDOMReady) y luego configure el hash de la URL a esa altura. Y en el documento principal, agregue un
onload
evento a la etiqueta iFrame que buscará la ubicación del iframe y extraerá el valor que necesita. Debido a que onDOMReady siempre ocurrirá antes del evento de carga del documento, puede estar bastante seguro de que el valor se comunicará correctamente sin una condición de carrera que complique las cosas.En otras palabras:
... en 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);
... y en el documento principal:
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 );
fuente
<iframe src="../Help.php#introduction" />
)sleep(5)
en su Help.php también debería ser una buena forma de probar cualquier condición de carrera. Si el iframe se dispara de alguna maneraonLoad
antesonDOMReady
, debería aparecer aquí.Encontré que lo siguiente funciona en Chrome, Firefox e IE11:
$('iframe').load(function () { $('iframe').height($('iframe').contents().height()); });
Cuando el contenido de Iframes termine de cargarse, el evento se activará y establecerá la altura de IFrames a la de su contenido. Esto solo funcionará para páginas dentro del mismo dominio que el del IFrame.
fuente
El código para hacer esto sin jQuery es trivial hoy en día:
const frame = document.querySelector('iframe') function syncHeight() { this.style.height = `${this.contentWindow.document.body.offsetHeight}px` } frame.addEventListener('load', syncHeight)
Para desenganchar el evento:
frame.removeEventListener('load', syncHeight)
fuente
No necesita jquery dentro del iframe para hacer esto, pero lo uso porque el código es mucho más simple ...
Pon esto en el documento dentro de tu iframe.
$(document).ready(function() { parent.set_size(this.body.offsetHeight + 5 + "px"); });
agregó cinco arriba para eliminar la barra de desplazamiento en ventanas pequeñas, nunca es perfecto en tamaño.
Y esto dentro de su documento principal.
function set_size(ht) { $("#iframeId").css('height',ht); }
fuente
esta es la respuesta correcta que funcionó para mí
$(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(); });
fuente
Una línea simple comienza con una altura mínima predeterminada y aumenta hasta el tamaño del contenido.
<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>
fuente
Las respuestas aceptadas
$('iframe').load
ahora producirán una.indexOf is not a function
error. Puede actualizarse a:$('iframe').on('load', function() { // ... });
Pocos otros similares a
.load
obsoletos desde jQuery 1.8: error "Uncaught TypeError: a.indexOf no es una función" al abrir un nuevo proyecto básicofuente
Esta es una solución gratuita de jQuery que puede funcionar con SPA dentro del iframe
document.getElementById('iframe-id').addEventListener('load', function () { let that = this; setTimeout(function () { that.style.height = that.contentWindow.document.body.offsetHeight + 'px'; }, 2000) // if you're having SPA framework (angularjs for example) inside the iframe, some delay is needed for the content to populate });
fuente
Esta es mi versión no-jquery amigable de ES6
document.querySelector('iframe').addEventListener('load', function() { const iframeBody = this.contentWindow.document.body; const height = Math.max(iframeBody.scrollHeight, iframeBody.offsetHeight); this.style.height = `${height}px`; });
fuente