bootstrap javascript iframe widget

javascript - bootstrap - iframe width



Cambiar el tamaƱo de un iframe basado en contenido (20)

obtén la altura del contenido del iframe y dáselo a este iframe

var iframes = document.getElementsByTagName("iframe"); for(var i = 0, len = iframes.length; i<len; i++){ window.frames[i].onload = function(_i){ return function(){ iframes[_i].style.height = window.frames[_i].document.body.scrollHeight + "px"; } }(i); }

Estoy trabajando en una aplicación similar a iGoogle. El contenido de otras aplicaciones (en otros dominios) se muestra mediante iframes.

¿Cómo cambio el tamaño de los iframes para que se ajusten a la altura del contenido de los iframes?

He intentado descifrar el javascript que usa Google pero está ofuscado, y hasta ahora la búsqueda en internet ha sido infructuosa.

Actualización: tenga en cuenta que el contenido se carga desde otros dominios, por lo que se aplica la política del mismo origen .


Algo en las líneas de esto creo que debería funcionar.

parent.document.getElementById(iFrameID).style.height=framedPage.scrollHeight;

Cargue esto con su cuerpo cargado en el contenido del iframe.


Aquí hay un enfoque de jQuery que agrega la información en json a través del atributo src del iframe. Aquí hay una demostración, redimensiona y desplaza esta ventana ... la url resultante con json se ve así ... http://fiddle.jshell.net/zippyskippy/RJN3G/show/#{docHeight:5124,windowHeight:1019,scrollHeight:571}#

Aquí está el código fuente de fiddle http://jsfiddle.net/zippyskippy/RJN3G/

function updateLocation(){ var loc = window.location.href; window.location.href = loc.replace(/#{.*}#/,"") + "#{docHeight:"+$(document).height() + ",windowHeight:"+$(window).height() + ",scrollHeight:"+$(window).scrollTop() +"}#"; }; //setInterval(updateLocation,500); $(window).resize(updateLocation); $(window).scroll(updateLocation);


Aquí hay una solución simple que utiliza una hoja de estilo generada dinámicamente y que recibe el mismo servidor que el contenido de iframe. Sencillamente, la hoja de estilo "sabe" lo que está en el iframe, y conoce las dimensiones a usar para diseñar el iframe. Esto evita las mismas restricciones de la política de origen.

http://www.8degrees.co.nz/2010/06/09/dynamically-resize-an-iframe-depending-on-its-content/

Por lo tanto, el código iframe suministrado tendría una hoja de estilo adjunta como ...

<link href="http://your.site/path/to/css?contents_id=1234&dom_id=iframe_widget" rel="stylesheet" type="text/css" /> <iframe id="iframe_widget" src="http://your.site/path/to/content?content_id=1234" frameborder="0" width="100%" scrolling="no"></iframe>

Esto requiere que la lógica del lado del servidor sea capaz de calcular las dimensiones del contenido renderizado del iframe.


Cuando desee alejar una página web para que se ajuste al tamaño del iframe:

  1. Debe cambiar el tamaño del iframe para que se ajuste al contenido.
  2. Luego debe alejar todo el iframe con el contenido de la página web cargada.

Aquí hay un ejemplo:

<div id="wrap"> <IFRAME ID="frame" name="Main" src ="http://www.google.com" /> </div>

<style type="text/css"> #wrap { width: 130px; height: 130px; padding: 0; overflow: hidden; } #frame { width: 900px; height: 600px; border: 1px solid black; } #frame { zoom:0.15; -moz-transform:scale(0.15);-moz-transform-origin: 0 0; } </style>


Esta respuesta solo es aplicable para sitios web que utilizan Bootstrap. La característica de inserción receptiva de Bootstrap hace el trabajo. Se basa en el ancho (no la altura) del contenido.

<!-- 16:9 aspect ratio --> <div class="embed-responsive embed-responsive-16by9"> <iframe class="embed-responsive-item" src="http://www.youtube.com/embed/WsFWhL4Y84Y"></iframe> </div>

jsfiddle: http://jsfiddle.net/00qggsjj/2/

http://getbootstrap.com/components/#responsive-embed


Esto es un poco complicado ya que debes saber cuándo se ha cargado la página iframe, lo cual es difícil cuando no tienes el control de su contenido. Es posible agregar un controlador de carga al iframe, pero lo he intentado en el pasado y tiene un comportamiento muy diferente en los navegadores (no adivine quién es el más molesto ...). Probablemente tendría que agregar una función a la página iframe que realiza el cambio de tamaño e inyectar un script en el contenido que escucha para cargar eventos o para cambiar el tamaño de los eventos, que luego llama a la función anterior. Estoy pensando en agregar una función a la página ya que quieres asegurarte de que esté segura, pero no tengo idea de lo fácil que será hacerlo.


Estoy implementando la solución de marco en marco de ConroyP para reemplazar una solución basada en la configuración de document.domain, pero encontré que es bastante difícil determinar la altura del contenido del iframe correctamente en diferentes navegadores (probando con FF11, Ch17 e IE9 en este momento) ).

ConroyP utiliza:

var height = document.body.scrollHeight;

Pero eso solo funciona en la carga inicial de la página. Mi iframe tiene contenido dinámico y necesito cambiar el tamaño del iframe en ciertos eventos.

Lo que terminé haciendo fue usar diferentes propiedades JS para los diferentes navegadores.

function getDim () { var body = document.body, html = document.documentElement; var bc = body.clientHeight; var bo = body.offsetHeight; var bs = body.scrollHeight; var hc = html.clientHeight; var ho = html.offsetHeight; var hs = html.scrollHeight; var h = Math.max(bc, bo, bs, hc, hs, ho); var bd = getBrowserData(); // Select height property to use depending on browser if (bd.isGecko) { // FF 11 h = hc; } else if (bd.isChrome) { // CH 17 h = hc; } else if (bd.isIE) { // IE 9 h = bs; } return h; }

getBrowserData () es una función de detección del navegador "inspirada" en http://docs.sencha.com/core/source/Ext.html#method-Ext-apply Ext Core

Eso funcionó bien para FF e IE pero luego hubo problemas con Chrome. Uno de ellos fue un problema de tiempo, al parecer, a Chrome le toma un tiempo configurar / detectar la altura del iframe. Y luego Chrome nunca devolvió la altura del contenido en el iframe correctamente si el iframe era más alto que el contenido. Esto no funcionaría con contenido dinámico cuando se reduce la altura.

Para resolver esto, siempre establezco el iframe a una altura baja antes de detectar la altura del contenido y luego establecer la altura del iframe en su valor correcto.

function resize () { // Reset the iframes height to a low value. // Otherwise Chrome won''t detect the content height of the iframe. setIframeHeight(150); // Delay getting the dimensions because Chrome needs // a few moments to get the correct height. setTimeout("getDimAndResize()", 100); }

El código no está optimizado, es de mis pruebas de desarrollo :)

Espero que alguien encuentre esto útil!


Finalmente encontré otra solución para enviar datos al sitio web principal desde iframe usando window.postMessage(message, targetOrigin); . Aquí te explico cómo lo hice.

Sitio A = http://foo.com Sitio B = http://bar.com

SiteB se está cargando en el sitio web de siteA

El sitio web de SiteB tiene esta línea

window.parent.postMessage("Hello From IFrame", "*");

o

window.parent.postMessage("Hello From IFrame", "http://foo.com");

Entonces siteA tiene este siguiente código

// Here "addEventListener" is for standards-compliant web browsers and "attachEvent" is for IE Browsers. var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; var eventer = window[eventMethod]; var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message"; // Listen to message from child IFrame window eventer(messageEvent, function (e) { alert(e.data); // Do whatever you want to do with the data got from IFrame in Parent form. }, false);

Si desea agregar una conexión de seguridad, puede usar esto si la condición está en el eventer(messageEvent, function (e) {})

if (e.origin == ''http://iframe.example.com'') { alert(e.data); // Do whatever you want to do with the data got from IFrame in Parent form. }

Para IE

Dentro de marco

window.parent.postMessage(''{"key":"value"}'',''*'');

Fuera de:

eventer(messageEvent, function (e) { var data = jQuery.parseJSON(e.data); doSomething(data.key); }, false);


La forma más sencilla de usar jQuery:

$("iframe") .attr({"scrolling": "no", "src":"http://www.someotherlink.com/"}) .load(function() { $(this).css("height", $(this).contents().height() + "px"); });


La solución en http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html funciona muy bien (usa jQuery):

<script type=”text/javascript”> $(document).ready(function() { var theFrame = $(”#iFrameToAdjust”, parent.document.body); theFrame.height($(document.body).height() + 30); }); </script>

No sé si necesitas agregar 30 a la longitud ... 1 funcionó para mí.

Para su información : Si ya tiene un atributo de "altura" en su iFrame, esto solo agrega style = "height: xxx". Esto podría no ser lo que quieres.


Los gadgets de iGoogle tienen que implementar activamente el cambio de tamaño, por lo que mi suposición es que en un modelo de varios dominios no puedes hacer esto sin que el contenido remoto participe de alguna manera. Si su contenido puede enviar un mensaje con el nuevo tamaño a la página del contenedor utilizando técnicas típicas de comunicación entre dominios, el resto es simple.


Si no necesita manejar el contenido de iframe de un dominio diferente, intente este código, resolverá el problema completamente y es simple:

<script language="JavaScript"> <!-- function autoResize(id){ var newheight; var newwidth; if(document.getElementById){ newheight=document.getElementById(id).contentWindow.document .body.scrollHeight; newwidth=document.getElementById(id).contentWindow.document .body.scrollWidth; } document.getElementById(id).height= (newheight) + "px"; document.getElementById(id).width= (newwidth) + "px"; } //--> </script> <iframe src="usagelogs/default.aspx" width="100%" height="200px" id="iframe1" marginheight="0" frameborder="0" onLoad="autoResize(''iframe1'');"></iframe>


Tengo una solución fácil y requiere que usted determine el ancho y la altura en el enlace, por favor intente (Funciona con la mayoría de los navegadores):

<a href=''#'' onClick=" document.getElementById(''myform'').src=''t2.htm'';document.getElementById(''myform'').width=''500px''; document.getElementById(''myform'').height=''400px''; return false">500x400</a>


Trabaja con jquery en carga (navegador cruzado):

<iframe src="your_url" marginwidth="0" marginheight="0" scrolling="No" frameborder="0" hspace="0" vspace="0" id="containiframe" onload="loaderIframe();" height="100%" width="100%"></iframe> function loaderIframe(){ var heightIframe = $(''#containiframe'').contents().find(''body'').height(); $(''#frame'').css("height", heightFrame); }

en cambiar el tamaño en la página de respuesta:

$(window).resize(function(){ if($(''#containiframe'').length !== 0) { var heightIframe = $(''#containiframe'').contents().find(''body'').height(); $(''#frame'').css("height", heightFrame); } });


Usando jQuery:

parent.html

<body> <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script> <style> iframe { width: 100%; border: 1px solid black; } </style> <script> function foo(w, h) { $("iframe").css({width: w, height: h}); return true; // for debug purposes } </script> <iframe src="child.html"></iframe> </body>

child.html

<body> <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script> <script> $(function() { var w = $("#container").css("width"); var h = $("#container").css("height"); var req = parent.foo(w, h); console.log(req); // for debug purposes }); </script> <style> body, html { margin: 0; } #container { width: 500px; height: 500px; background-color: red; } </style> <div id="container"></div> </body>


puede ser un poco tarde, ya que todas las demás respuestas son antiguas :-) pero ... aquí está mi solución. Probado en FF real, Chrome y Safari 5.0.

css:

iframe {border:0; overflow:hidden;}

javascript:

$(document).ready(function(){ $("iframe").load( function () { var c = (this.contentWindow || this.contentDocument); if (c.document) d = c.document; var ih = $(d).outerHeight(); var iw = $(d).outerWidth(); $(this).css({ height: ih, width: iw }); }); });

Espero que esto ayude a cualquiera.


https://developer.mozilla.org/en/DOM/window.postMessage

window.postMessage ()

window.postMessage es un método para habilitar de forma segura la comunicación de origen cruzado. Normalmente, los scripts en diferentes páginas solo pueden acceder entre sí si y solo si las páginas que los ejecutaron están en ubicaciones con el mismo protocolo (generalmente ambos http), el número de puerto (80 es el predeterminado para http) y el host (módulo document.domain está siendo establecido por ambas páginas al mismo valor). window.postMessage proporciona un mecanismo controlado para eludir esta restricción de manera segura cuando se usa correctamente.

Resumen

window.postMessage, cuando se le llama, hace que se envíe un MessageEvent a la ventana de destino cuando se complete cualquier script pendiente que deba ejecutarse (por ejemplo, los controladores de eventos restantes si se llama a window.postMessage desde un controlador de eventos, los tiempos de espera pendientes establecidos previamente, etc.) ). MessageEvent tiene el tipo de mensaje, una propiedad de datos que se establece en el valor de la cadena del primer argumento proporcionado a window.postMessage, una propiedad de origen correspondiente al origen del documento principal en la ventana que llama window.postMessage en la ventana de tiempo. Se llamó a postMessage y una propiedad de origen que es la ventana desde la que se llama a window.postMessage. (Otras propiedades estándar de eventos están presentes con sus valores esperados).

La biblioteca iFrame-Resizer usa postMessage para mantener un iFrame del tamaño de su contenido, junto con MutationObserver para detectar cambios en el contenido y no depende de jQuery.

https://github.com/davidjbradshaw/iframe-resizer

jQuery: bondad de secuencias de comandos entre dominios

http://benalman.com/projects/jquery-postmessage-plugin/

Tiene demo de redimensionar ventana iframe ...

http://benalman.com/code/projects/jquery-postmessage/examples/iframe/

Este artículo muestra cómo eliminar la dependencia de jQuery ... Plus tiene mucha información útil y enlaces a otras soluciones.

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

Ejemplo de Barebones ...

http://onlineaspect.com/uploads/postmessage/parent.html

HTML 5 borrador de trabajo en window.postMessage

http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages

John Resig en mensajería de ventana cruzada

http://ejohn.org/blog/cross-window-messaging/


Tuvimos este tipo de problema, pero un poco inverso a su situación: proporcionábamos el contenido de iframed a sitios en otros dominios, por lo que la misma política de origen también era un problema. Después de pasar muchas horas rastreando en google, finalmente encontramos una solución viable (algo ...) que puede adaptar a sus necesidades.

Hay una forma de evitar la misma política de origen, pero requiere cambios tanto en el contenido de iframed como en la página de marcos, por lo que si no tiene la capacidad de solicitar cambios en ambos lados, este método no será muy útil para usted. Me temo que.

Hay una peculiaridad del navegador que nos permite saltear la misma política de origen: javascript puede comunicarse con páginas en su propio dominio o con páginas que tiene iframed, pero nunca páginas en las que está enmarcado, por ejemplo, si tiene:

www.foo.com/home.html, which iframes |-> www.bar.net/framed.html, which iframes |-> www.foo.com/helper.html

luego home.html puede comunicarse con framed.html (iframed) y helper.html (mismo dominio).

Communication options for each page: +-------------------------+-----------+-------------+-------------+ | | home.html | framed.html | helper.html | +-------------------------+-----------+-------------+-------------+ | www.foo.com/home.html | N/A | YES | YES | | www.bar.net/framed.html | NO | N/A | YES | | www.foo.com/helper.html | YES | YES | N/A | +-------------------------+-----------+-------------+-------------+

framed.html puede enviar mensajes a helper.html (iframed) pero no a home.html (el hijo no puede comunicarse entre dominios con el padre).

La clave aquí es que helper.html puede recibir mensajes de framed.html y también puede comunicarse con home.html .

Esencialmente, cuando se carga framed.html , su propia altura, dice helper.html , que pasa el mensaje a home.html , que luego puede cambiar el tamaño del iframe en el que se encuentra framed.html .

La forma más sencilla que encontramos para pasar mensajes de framed.html a helper.html fue a través de un argumento de URL. Para hacer esto, framed.html tiene un iframe con src='''' especificado. Cuando su onload dispara, evalúa su propia altura y establece el src del iframe en este punto en helper.html?height=N

¡Aquí hay una explicación de cómo Facebook lo maneja, que puede ser un poco más claro que el mío arriba!

Código

En www.foo.com/home.html , se www.foo.com/home.html el siguiente código javascript (se puede cargar desde un archivo .js en cualquier dominio, por cierto ...):

<script> // Resize iframe to full height function resizeIframe(height) { // "+60" is a general rule of thumb to allow for differences in // IE & and FF height reporting, can be adjusted as required.. document.getElementById(''frame_name_here'').height = parseInt(height)+60; } </script> <iframe id=''frame_name_here'' src=''http://www.bar.net/framed.html''></iframe>

En www.bar.net/framed.html :

<body onload="iframeResizePipe()"> <iframe id="helpframe" src='''' height=''0'' width=''0'' frameborder=''0''></iframe> <script type="text/javascript"> function iframeResizePipe() { // What''s the page height? var height = document.body.scrollHeight; // Going to ''pipe'' the data to the parent through the helpframe.. var pipe = document.getElementById(''helpframe''); // Cachebuster a precaution here to stop browser caching interfering pipe.src = ''http://www.foo.com/helper.html?height=''+height+''&cacheb=''+Math.random(); } </script>

Contenido de www.foo.com/helper.html :

<html> <!-- This page is on the same domain as the parent, so can communicate with it to order the iframe window resizing to fit the content --> <body onload="parentIframeResize()"> <script> // Tell the parent iframe what height the iframe needs to be function parentIframeResize() { var height = getParam(''height''); // This works as our parent''s parent is on our domain.. parent.parent.resizeIframe(height); } // Helper function, parse param from request string function getParam( name ) { name = name.replace(/[/[]/,"///[").replace(/[/]]/,"///]"); var regexS = "[//?&]"+name+"=([^&#]*)"; var regex = new RegExp( regexS ); var results = regex.exec( window.location.href ); if( results == null ) return ""; else return results[1]; } </script> </body> </html>


<html> <head> <script> function frameSize(id){ var frameHeight; document.getElementById(id).height=0 + "px"; if(document.getElementById){ newheight=document.getElementById(id).contentWindow.document.body.scrollHeight; } document.getElementById(id).height= (frameHeight) + "px"; } </script> </head> <body> <iframe id="frame" src="startframe.html" frameborder="0" marginheight="0" hspace=20 width="100%" onload="javascript:frameSize(''frame'');"> <p>This will work, but you need to host it on an http server, you can do it locally. </p> </body> </html>