Cambiar el tamaño de la altura del iframe según la altura del contenido en él

Estoy abriendo mi página de blog en mi website. El problema es que puedo dar un ancho a un iframe, pero la altura debe ser dinámica para que no haya una barra de desplazamiento en el iframe, y parece una sola página …

He intentado varios códigos JavaScript para calcular el alto del contenido, pero todos dan un error de permiso de acceso denegado y no sirve de nada.

<iframe src="http://bagtheplanet.blogspot.com/" name="ifrm" id="ifrm" width="1024px" ></iframe> 

¿Podemos usar Ajax para calcular la altura o quizás usar PHP?

Para responder directamente sus dos preguntas secundarias: No, no puede hacer esto con Ajax, ni puede calcularlo con PHP.

Lo que hice en el pasado es utilizar un activador desde la página iframe'd en window.onload (NO domready , ya que las imágenes tardan un poco en cargarse) para pasar la altura del cuerpo de la página al elemento principal.

 <body onload='parent.resizeIframe(document.body.scrollHeight)'> 

Entonces parent.resizeIframe ve así:

 function resizeIframe(newHeight) { document.getElementById('blogIframe').style.height = parseInt(newHeight,10) + 10 + 'px'; } 

Et voila, usted tiene un resizer robusto que se dispara una vez que la página está completamente renderizada sin contenido desagradable contentdocument vs contentWindow violín 🙂

Claro, ahora las personas verán primero su iframe a la altura pnetworkingeterminada, pero esto se puede manejar fácilmente al ocultar su iframe al principio y solo mostrando una image de "carga". Luego, cuando la function resizeIframe , coloque dos líneas adicionales que oculten la image de carga y muestre el iframe para ese falso aspecto de Ajax.

Por supuesto, esto solo funciona desde el mismo dominio, por lo que es posible que desee tener un script PHP proxy para incrustar este material, y una vez que vaya allí, también puede insert el feed RSS de su blog directamente en su sitio con PHP.

Puedes hacer esto con JavaScript.

 document.getElementById('foo').height = document.getElementById('foo').contentWindow.document.body.scrollHeight + "px"; 

Ajustar los contenidos de IFRAME es algo fácil de encontrar en Google . Aquí hay una solución :

 <script type="text/javascript"> function autoIframe(frameId) { try { frame = document.getElementById(frameId); innerDoc = (frame.contentDocument) ? frame.contentDocument : frame.contentWindow.document; objToResize = (frame.style) ? frame.style : frame; objToResize.height = innerDoc.body.scrollHeight + 10; } catch(err) { window.status = err.message; } } </script> 

Esto, por supuesto, no resuelve el problema de dominio cruzado que está teniendo … Establecer document.domain podría ayudar si estos sitios están en el mismo lugar. No creo que haya una solución si está creando sitios aleatorios.

Aquí está mi solución al problema usando MooTools que funciona en Firefox 3.6, Safari 4.0.4 e Internet Explorer 7:

 var iframe_container = $('iframe_container_id'); var iframe_style = { height: 300, width: '100%' }; if (!Browser.Engine.trident) { // IE has hasLayout issues if iframe display is none, so don't use the loading class iframe_container.addClass('loading'); iframe_style.display = 'none'; } this.iframe = new IFrame({ frameBorder: 0, src: "http://www.youriframeurl.com/", styles: iframe_style, events: { 'load': function() { var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document; var h = this.measure(function(){ return innerDoc.body.scrollHeight; }); this.setStyles({ height: h.toInt(), display: 'block' }); if (!Browser.Engine.trident) { iframe_container.removeClass('loading'); } } } }).inject(iframe_container); 

Estilice la class "carga" para mostrar un gráfico de carga de Ajax en el medio del contenedor de iframes. Luego, para los browseres que no sean Internet Explorer, se mostrará el IFRAME de altura completa una vez que se complete la carga de su contenido y se elimine el gráfico de carga.

A continuación está mi controller de events onload .

Uso un IFRAME dentro de un dialog de interfaz de usuario de jQuery . Los diferentes usos necesitarán algunos ajustes. Esto parece ser el truco para mí (por ahora) en Internet Explorer 8 y Firefox 3.5. Puede necesitar algunos ajustes adicionales, pero la idea general debe ser clara.

  function onLoadDialog(frame) { try { var body = frame.contentDocument.body; var $body = $(body); var $frame = $(frame); var contentDiv = frame.parentNode; var $contentDiv = $(contentDiv); var savedShow = $contentDiv.dialog('option', 'show'); var position = $contentDiv.dialog('option', 'position'); // disable show effect to enable re-positioning (UI bug?) $contentDiv.dialog('option', 'show', null); // show dialog, otherwise sizing won't work $contentDiv.dialog('open'); // Maximize frame width in order to determine minimal scrollHeight $frame.css('width', $contentDiv.dialog('option', 'maxWidth') - contentDiv.offsetWidth + frame.offsetWidth); var minScrollHeight = body.scrollHeight; var maxWidth = body.offsetWidth; var minWidth = 0; // decrease frame width until scrollHeight starts to grow (wrapping) while (Math.abs(maxWidth - minWidth) > 10) { var width = minWidth + Math.ceil((maxWidth - minWidth) / 2); $body.css('width', width); if (body.scrollHeight > minScrollHeight) { minWidth = width; } else { maxWidth = width; } } $frame.css('width', maxWidth); // use maximum height to avoid vertical scrollbar (if possible) var maxHeight = $contentDiv.dialog('option', 'maxHeight') $frame.css('height', maxHeight); $body.css('width', ''); // correct for vertical scrollbar (if necessary) while (body.clientWidth < maxWidth) { $frame.css('width', maxWidth + (maxWidth - body.clientWidth)); } var minScrollWidth = body.scrollWidth; var minHeight = Math.min(minScrollHeight, maxHeight); // descrease frame height until scrollWidth decreases (wrapping) while (Math.abs(maxHeight - minHeight) > 10) { var height = minHeight + Math.ceil((maxHeight - minHeight) / 2); $body.css('height', height); if (body.scrollWidth < minScrollWidth) { minHeight = height; } else { maxHeight = height; } } $frame.css('height', maxHeight); $body.css('height', ''); // reset widths to 'auto' where possible $contentDiv.css('width', 'auto'); $contentDiv.css('height', 'auto'); $contentDiv.dialog('option', 'width', 'auto'); // re-position the dialog $contentDiv.dialog('option', 'position', position); // hide dialog $contentDiv.dialog('close'); // restre show effect $contentDiv.dialog('option', 'show', savedShow); // open using show effect $contentDiv.dialog('open'); // remove show effect for consecutive requests $contentDiv.dialog('option', 'show', null); return; } //An error is raised if the IFrame domain != its container's domain catch (e) { window.status = 'Error: ' + e.number + '; ' + e.description; alert('Error: ' + e.number + '; ' + e.description); } }; 

Cómo ajustar dinámicamente la altura de un iframe es muy simple y lo probé.

La respuesta de @SchizoDuckie es muy elegante y liviana, pero debido a la falta de implementación de Webkit para scrollHeight (ver aquí ), no funciona en los browseres basados ​​en Webkit (Safari, Chrome, varias plataforms mobilees).

Para que esta idea básica funcione en Webkit junto con los browseres Gecko y Trident, basta con replace

 <body onload='parent.resizeIframe(document.body.scrollHeight)'> 

con

 <body onload='parent.resizeIframe(document.body.offsetHeight)'> 

Mientras todo esté en el mismo dominio, esto funciona bastante bien.

Acabo de pasar la mayor parte de 3 días luchando con esto. Estoy trabajando en una aplicación que carga otras aplicaciones en sí misma mientras mantiene un encabezado fijo y un pie de página fijo. Esto es lo que se me ocurrió. (También utilicé EasyXDM, con éxito, pero lo saqué más tarde para usar esta solución).

Asegúrese de ejecutar este código DESPUÉS de que exista el <iframe> en el DOM. Ponlo en la página que atrae el iframe (el padre).

 // get the iframe var theFrame = $("#myIframe"); // set its height to the height of the window minus the combined height of fixed header and footer theFrame.height(Number($(window).height()) - 80); function resizeIframe() { theFrame.height(Number($(window).height()) - 80); } // setup a resize method to fire off resizeIframe. // use timeout to filter out unnecessary firing. var TO = false; $(window).resize(function() { if (TO !== false) clearTimeout(TO); TO = setTimeout(resizeIframe, 500); //500 is time in miliseconds }); 

El truco es adquirir todos los events de iframe necesarios de un script externo. Por ejemplo, tiene un script que crea el iFrame utilizando document.createElement; en este mismo script, tienes acceso temporal al contenido del iFrame.

 var dFrame = document.createElement("iframe"); dFrame.src = "http://www.example.com"; // Acquire onload and resize the iframe dFrame.onload = function() { // Setting the content window's resize function tells us when we've changed the height of the internal document // It also only needs to do what onload does, so just have it call onload dFrame.contentWindow.onresize = function() { dFrame.onload() }; dFrame.style.height = dFrame.contentWindow.document.body.scrollHeight + "px"; } window.onresize = function() { dFrame.onload(); } 

Esto funciona porque dFrame permanece en el scope de esas funciones, lo que le da acceso al elemento iFrame externo desde el scope del marco, lo que le permite ver la altura real del documento y expandirlo según sea necesario. Este ejemplo funcionará en Firefox pero en ningún otro lugar; Podría darte las soluciones, pero puedes averiguar el rest;)

Pruebe esto, puede cambiar incluso cuando lo desee. este ejemplo usa jQuery.

 $('#iframe').live('mousemove', function (event) { var theFrame = $(this, parent.document.body); this.height($(document.body).height() - 350); }); 

Intenta usar scrolling=no atributo en la label iframe. Mozilla también tiene una propiedad de CSS overflow-x y overflow-y que puede considerar.

En términos de altura, también puedes probar height=100% en la label iframe.