javascript - tag - iframe url
iframe Ajuste automático de altura a medida que cambia el contenido (4)
Tengo un iframe como se puede ver en el siguiente enlace;
El iframe es la reserva en línea en el centro de la pantalla. El problema que tengo es que aunque la altura del iframe está bien a medida que se carga la página, lo necesito para ajustar automáticamente la altura a medida que se ajusta el contenido de la página. Por ejemplo, si hago una búsqueda de código postal en la reserva en línea, se crea un menú desplegable y luego el botón "Siguiente paso" no se puede ver.
Lo que necesito que suceda es que cuando el contenido de la reserva en línea cambia, el iframe se ajusta automáticamente a la nueva altura del iframe (dinámicamente), ya que no carga ninguna otra página.
He intentado varios scripts diferentes utilizando jquery para intentar resolver este problema, pero parece que todos ellos solo ajustan automáticamente la altura del iframe cuando se carga la página por primera vez y no como el contenido del iframe cambia.
¿Es esto posible hacer?
El código que tengo en este momento es con una altura establecida en este momento:
<div id="main-online-booking">
<iframe id="main-online-frame" class="booking-dimensions" src="http://www.marandy.com/one2oneob/login-guest.php" scrolling="no" frameborder="0"></iframe>
</div>
#main-online-booking {
height: 488px;
border-bottom: 6px #939393 solid;
border-left: 6px #939393 solid;
border-right: 6px #939393 solid;
z-index: 4;
background-color: #fff;
}
.booking-dimensions {
width: 620px;
height: 488px;
}
¡Si alguien me puede ayudar con esto, sería muy apreciado!
El navegador moderno y en parte IE8 tienen algunas características nuevas que hacen que esta tarea sea más fácil de lo que solía ser.
PostMessage
La API de postMessage proporciona un método simple para comunicarse entre un iFrame y su padre.
Para enviar un mensaje a la página principal, debe llamarlo de la siguiente manera.
parent.postMessage(''Hello parent'',''http://origin-domain.com'');
En la otra dirección podemos enviar el mensaje al iFrame con el siguiente código.
var iframe = document.querySelector(''iframe'');
iframe.contentWindow.postMessage(''Hello my child'', ''http://remote-domain.com:8080'');
Para recibir un mensaje, cree un evento listerner para el evento de mensaje.
function receiveMessage(event)
{
if (event.origin !== "http://remote-domain.com:8080")
return;
console.log(event.data);
}
if (''addEventListener'' in window){
window.addEventListener(''message'', receiveMessage, false);
} else if (''attachEvent'' in window){ //IE
window.attachEvent(''onmessage'', receiveMessage);
Estos ejemplos utilizan la propiedad de origen para limitar dónde se envía el mensaje y para verificar de dónde proviene. Es posible especificar *
para permitir el envío a cualquier dominio y, en algunos casos, es posible que desee aceptar mensajes de cualquier dominio. Sin embargo, si hace esto, debe considerar las implicaciones de seguridad e implementar sus propias comprobaciones en el mensaje entrante para asegurarse de que contenga lo que espera. En este caso, el iframe puede publicar su altura en ''*'', ya que podríamos tener más de un dominio principal. Sin embargo, es una buena idea comprobar que los mensajes entrantes son del iFrame.
function isMessageFromIFrame(event,iframe){
var
origin = event.origin,
src = iframe.src;
if ((''''+origin !== ''null'') && (origin !== src.substr(0,origin.length))) {
throw new Error(
''Unexpect message received from: '' + origin +
'' for '' + iframe.id + ''. Message was: '' + event.data
);
}
return true;
}
MutationObserver
El otro avance en broswers más modernos es MutationObserver que le permite observar los cambios en el DOM; por lo tanto, ahora es posible detectar cambios que podrían afectar el tamaño del iFrame sin tener que sondear constantemente con setInterval.
function createMutationObserver(){
var
target = document.querySelector(''body''),
config = {
attributes : true,
attributeOldValue : false,
characterData : true,
characterDataOldValue : false,
childList : true,
subtree : true
},
observer = new MutationObserver(function(mutations) {
parent.postMessage(''[iframeResize]''+document.body.offsetHeight,''*'');
});
log(''Setup MutationObserver'');
observer.observe(target, config);
}
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
if (MutationObserver){
createMutationObserver();
}
Trabajando una altura precisa
Obtener una altura precisa para el iFrame no es tan simple como debería, ya que puede elegir entre seis propiedades diferentes que puede verificar y ninguna de ellas le da una respuesta correcta. La mejor solución que he encontrado es esta función que funciona siempre que no uses CSS para desbordar la etiqueta del cuerpo.
function getIFrameHeight(){
function getComputedBodyStyle(prop) {
return parseInt(
document.defaultView.getComputedStyle(document.body, null),
10
);
}
return document.body.offsetHeight +
getComputedBodyStyle(''marginTop'') +
getComputedBodyStyle(''marginBottom'');
}
Esta es la versión de IE9, para la versión mucho más larga de IE8 vea esta answer .
Si desborda el cuerpo y no puede arreglar su código para detener esto, entonces usar las propiedades offsetHeight
o scrollHeight
de document.documentElement
son sus mejores opciones. Ambos tienen ventajas y desventajas, y lo mejor es probar ambos y ver cuál funciona para usted.
Otros asuntos
Otras cosas a considerar incluyen tener más de un iFrame en la página, CSS: Checkbox y: Hover eventos que causan el cambio de tamaño de la página, evitando el uso de la altura automática en las etiquetas del cuerpo y html de los iFrames y, por último, el tamaño de la ventana.
Biblioteca IFrame Resizer
He envuelto todo esto en una simple biblioteca sin dependencia, que también proporciona algunas funciones adicionales que no se tratan aquí.
https://github.com/davidjbradshaw/iframe-resizer
Esto funciona con IE8 +.
Escribí este guión y está funcionando perfectamente para mí. ¡Sientase libre de usarlo!
function ResizeIframeFromParent(id) {
if (jQuery(''#''+id).length > 0) {
var window = document.getElementById(id).contentWindow;
var prevheight = jQuery(''#''+id).attr(''height'');
var newheight = Math.max( window.document.body.scrollHeight, window.document.body.offsetHeight, window.document.documentElement.clientHeight, window.document.documentElement.scrollHeight, window.document.documentElement.offsetHeight );
if (newheight != prevheight && newheight > 0) {
jQuery(''#''+id).attr(''height'', newheight);
console.log("Adjusting iframe height for "+id+": " +prevheight+"px => "+newheight+"px");
}
}
}
Puede llamar a la función dentro de un bucle:
<script>
jQuery(document).ready(function() {
// Try to change the iframe size every 2 seconds
setInterval(function() {
ResizeIframeFromParent(''iframeid'');
}, 2000);
});
</script>
usa este script:
$(document).ready(function () {
// Set specific variable to represent all iframe tags.
var iFrames = document.getElementsByTagName(''iframe'');
// Resize heights.
function iResize() {
// Iterate through all iframes in the page.
for (var i = 0, j = iFrames.length; i < j; i++) {
// Set inline style to equal the body height of the iframed content.
iFrames[i].style.height = iFrames[i].contentWindow.document.body.offsetHeight + ''px'';
}
}
// Check if browser is Safari or Opera.
if ($.browser.safari || $.browser.opera) {
// Start timer when loaded.
$(''iframe'').load(function () {
setTimeout(iResize, 0);
});
// Safari and Opera need a kick-start.
for (var i = 0, j = iFrames.length; i < j; i++) {
var iSource = iFrames[i].src;
iFrames[i].src = '''';
iFrames[i].src = iSource;
}
} else {
// For other good browsers.
$(''iframe'').load(function () {
// Set inline style to equal the body height of the iframed content.
this.style.height = this.contentWindow.document.body.offsetHeight + ''px'';
});
}
});
Nota: utilízalo en el servidor web.
setInterval
los solamente (Corregido debido a los avances en la tecnología del navegador, vea la respuesta de David Bradshaw ). Una forma compatible hacia atrás para lograr esto con un iframe es usar setInterval
y vigilar usted mismo el contenido del iframe. Cuando cambia su altura, actualiza el tamaño del iframe. No hay tal evento que puedas escuchar que desafortunadamente lo hará más fácil.
Un ejemplo básico , esto solo funcionará si el contenido del iframe que ha cambiado de tamaño es parte del flujo de la página principal. Si los elementos son flotados o posicionados, tendrá que apuntarlos específicamente para buscar cambios de altura.
jQuery(function($){
var lastHeight = 0, curHeight = 0, $frame = $(''iframe:eq(0)'');
setInterval(function(){
curHeight = $frame.contents().find(''body'').height();
if ( curHeight != lastHeight ) {
$frame.css(''height'', (lastHeight = curHeight) + ''px'' );
}
},500);
});
Obviamente, dependiendo de lo que desee, puede modificar la perspectiva de este código para que funcione desde el iframe, en sí mismo, en lugar de esperar ser parte de la página principal.
problema de dominio cruzado
El problema que encontrará es que, debido a la seguridad del navegador, no le permitirá acceder al contenido del iframe si está en un host diferente a la página principal, por lo que no hay nada que pueda hacer a menos que tenga una forma de agregar Cualquier script para el html que aparece en el iframe.
ajax
Algunos otros sugieren que se intente utilizar el servicio de terceros a través de AJAX, a menos que el servicio sea compatible con este método, será muy improbable que pueda hacerlo funcionar, especialmente si es un servicio de reserva el que más probablemente necesitará. para operar sobre https / ssl.
Como parece que tiene control total sobre el contenido de iframe, tiene todas las opciones abiertas para usted, AJAX con JSONP sería una opción. Sin embargo, una palabra de advertencia. Si su sistema de reservaciones es multietápico, debe asegurarse de tener una interfaz de usuario bien diseñada, y posiblemente algún código de administración de fragmentos / historial, si va a seguir la ruta AJAX. Todo porque nunca se puede saber cuándo un usuario decidirá navegar hacia adelante o hacia atrás en su navegador (que un iframe manejaría automáticamente, dentro de lo razonable). Una interfaz de usuario bien diseñada puede impedir que los usuarios hagan esto.
comunicación entre dominios
Si tiene control de ambos lados (lo que suena como si lo tuviera), también tiene la opción de comunicación entre dominios utilizando window.postMessage
; consulte aquí para obtener más información https://developer.mozilla.org/en-US/docs/DOM/window.postMessage