2009-02-08 12 views
68

Estoy abriendo la página de mi blog en mi sitio web. 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 ...Cambiar el tamaño de la altura del iframe de acuerdo con la altura del contenido en él

He intentado varios códigos JavaScript para calcular el alto del contenido, pero todos dan un denegado el permiso de acceso error 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 tal vez usar PHP?

Respuesta

-3

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

En cuanto a la altura, también puede probar height=100% en la etiqueta iframe.

+0

altura = 100% no hace nada. – flavour404

+0

height = 100% no funciona en iframes. – Richard

4

Ajustar el contenido de IFRAME es algo fácil de find on Google. Aquí es one solution:

<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> 

Por supuesto, esto no resuelve el problema de varios dominios que está teniendo ... Ajuste 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.

+1

Le falta una unidad en la asignación de altura, es decir, 'px'. ¿Esto no causa una falla en el modo estándar? –

+0

sí, claro ... mybad –

8

Puede hacerlo con JavaScript.

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

El guión me confunde. Me gusta practicar con un sitio real: mathsearchun.blogspot.com/. ¿El "id" es el div más interno "HTML3" o el div "outer-wrapper" más externo? Obtuve errores como "contentWindow no está definido" y "document.getElementById (" id ") es nulo", en Firebug. ¿Qué quieren decir? –

+0

El elemento que desea obtener es el iframe, Amazon en su caso, supongo. "contentWindow no está definido" probablemente signifique que el elemento que tomó no tiene esa propiedad/elemento. Debe usar document.getElementById ("amazon") para obtener su iframe. –

+1

Esto funciona en Chrome e IE, pero no en Firefox, ¿puedes mejorar esto para incluir Firefox? –

60

para responder directamente a sus dos preguntas secundarias: No, no se puede hacer esto con el Ajax, ni se puede calcular con PHP.

Lo que he hecho en el pasado es usar un desencadenador de la página iframe'd en window.onload (NO , 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 el parent.resizeIframe se parece a esto:

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

Et voila, usted tiene un cambio de tamaño robusto que desencadena una vez que la página es totalmente generada sin desagradable contentdocument vs contentWindow tocar el violín :)

Claro, ahora las personas verán su iframe a la altura predeterminada primero, pero esto puede manejarse fácilmente al ocultar su iframe al principio y simplemente mostrando una imagen de 'carga'. Luego, cuando se active la función resizeIframe, coloque dos líneas adicionales que oculten la imagen 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 esto, y una vez que vaya allí, también puede insertar el feed RSS de su blog directamente en su sitio con PHP.

+0

Estoy usando iframe para cargar páginas. Mi iframe está en la página principal, que no se vuelve a cargar una vez cargado. Solo las páginas en iframe cambian según el enlace al que se hace clic desde la página principal que se dirige al iframe. ¿Cómo ajusto la altura del iframe en este caso? –

+0

Agregué esto al final de la página de mi iframe ... el tiempo de carga estaba provocando una altura falsa de px cuando estaba ubicado en el evento de carga del cuerpo. atwellpub

+0

@SchizoDuckie muy buena respuesta breve y simple –

0

Debajo está mi controlador de eventos onload.

Uso un IFRAME en un cuadro de diálogo jQuery UI. 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 retoques 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'); 
     // restore 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); 
    } 
}; 
2

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); 

estilo de la clase "carga" para mostrar un gráfico de carga Ajax en el medio del contenedor iframe. Luego, para los navegadores 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.

0

El truco consiste en adquirir todos los eventos 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 se mantiene en su alcance en esas funciones, que le da acceso al elemento de marco flotante externo dentro del ámbito de aplicación del marco, lo que permite ver la altura real de documentos y ampliar según sea necesario. Este ejemplo funcionará en Firefox pero en ningún otro lugar; Podría darle las soluciones, pero puede averiguar el resto;)

+0

Disparador feliz en la respuesta. Scott arriba usa un script similar, pero la inclusión de contentWindow.onresize le permite cambiar el tamaño del iframe si su contenido cambia. También es útil para iframes de ancho fluido. –

+0

¿A qué se refiere 'fobj' en este script? – akaihola

+0

Creo que fue un error de transcripción. Copié código y olvidé cambiar fobj en un contexto; debería ser dFrame. Solucionado en respuesta. –

0

@ La respuesta de SchizoDuckie es muy elegante y ligera, pero debido a la falta de implementación de Webkit para scrollHeight (ver here), no funciona en navegadores basados ​​en Webkit (Safari, Chrome, varias plataformas móviles).

Por esta idea básica para trabajar en Webkit, junto con los navegadores Gecko y Trident, solo hay que sustituir

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

con

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

En tanto que todo está en el mismo dominio, esto funciona muy bien.

+0

Según http://www.quirksmode.org/dom/w3c_cssom.html y una prueba rápida, scrollHeight funciona en Safari y Chrome (OS X). OffsetHeight no funcionó correctamente en ambos navegadores en mis pruebas. – user462982

0

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);   
}); 
0

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é después para usar esta solución.)

Asegúrese de ejecutar este código DESPUÉS de que el exista 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 
}); 
Cuestiones relacionadas