Hacer iframes responsive

Hacer iframes responsive
La creación de un iframe que funcione de manera Responsive correcta es complicada. En el siguiente artículo exponemos un método que hace que funcione bien utilizando la API postMessage para la comunicación entre el script del documento incrustado y el script del documento de alojamiento. Aunque tiene la limitación de la necesidad de tener acceso a ambos documentos, sigue siendo útil.

1. Determinar la altura del contenido del iframe al cargar la página

En primer lugar, hay dos secuencias de comandos a tener en cuenta

  • iframe.js - el script asociado con el documento iframe
  • parent.js - el script asociado con el documento donde se carga el iframe

En iframe.js, tenemos que determinar la altura del documento antes de que podamos pasarlo al documento de nivel superior. Esto lo hacemos esto obteniendo el  scrollHeight del elemento principal (#main-element) dentro del documento. 

var documentHeight = document.getElementById(‘main-element').scrollHeight;>

Usamos la altura del elemento principal del contenedor en lugar de sólo el body porque el uso del elemento body provoca un bucle infinito cuando lo repetimos en el cambio de tamaño de la ventana (ver paso 4).

2. Pasar la altura al documento de alojamiento

Una vez que tenemos la altura, podemos utilizar la API postMessage para enviar el mensaje a parent.js.

// Add some unique identifier to the string being passed
var message = 'documentHeight:'+documentHeight;
 
// Pass message to (any) parent document
parent.postMessage(message, "*");

Entonces, en parent.js, añadimos un detector de eventos para el mensaje. El método que utilizamos está basado en un artículo de David Walsh .

// Setup event listener
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";  
var eventer = window[eventMethod];  
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen for event
eventer(messageEvent,function(e) {
  // Check that message being passed is the documentHeight
  if (  (typeof e.data === 'string') && (e.data.indexOf('documentHeight:') > -1) ) {
    // Split string from identifier
    var height = e.data.split('documentHeight:')[1];
   // do stuff with the height
  } 
},false);

3. Cambiar la altura del <iframe> de forma apropiada

Cuando recibimos la nueva altura desde el iframe.js, podemos cambiar la altura del <iframe> en el documento principal. 

var height = e.data.split('documentHeight:')[1],  
    height = parseInt(height) + 30; // add a bit of extra space as buffer
// Change height of <iframe> element
document.getElementById('myIframe').height = height + 'px';

4. Repetir el cambio de tamaño del iframe

De vuelta en iframe.js, podemos enviar la nueva altura al parent.js cada vez que cambie la altura del documento. Usando window.onresize, podemos comprobar si el documentHeight ha cambiado significativamente (en este caso por lo menos 10px), y a continuación, enviar la nueva altura a parent.js

// On resize of the window, recalculate the height of the main element, 
// and pass to the parent document again
window.onresize = function(event) {  
    var newDocumentHeight = document.getElementById(‘main-element').scrollHeight;
    var heightDiff = documentHeight - newDocumentHeight;
 
    // If difference between current height and new height is more than 10px
    if ( heightDiff > 10 | heightDiff < -10 ) {
        documentHeight = newDocumentHeight;
        message = 'documentHeight:'+documentHeight;
        parent.postMessage(message,"*");
    }
}

Una vez que el mensaje se envía a parent.js , la altura del <iframe> se actualizará.

La razón por la que no usamos el elemento body para comprobar la altura del contenido anidado es porque, cuando cambia el tamaño del <iframe> en el documento de nivel superior, esto conlleva una modificación en la altura del elemento body en el documento del iframe, causando un bucle infinito.

Comentarios

Sin comentarios
Ha habido un error en el envío
Comentario enviado. Será revisado por la moderación antes de ser publicado.

Deja tu comentario

Tu nombre:
Tu email:
Tu comentario: