Probé algunas soluciones pero no tuve éxito. Me pregunto si existe una solución preferiblemente con un tutorial fácil de seguir.
Probé algunas soluciones pero no tuve éxito. Me pregunto si existe una solución preferiblemente con un tutorial fácil de seguir.
Respuestas:
Tienes tres alternativas:
Esta es una biblioteca simple para mantener los iFrames del tamaño de su contenido. Utiliza las API PostMessage y MutationObserver, con alternativas para IE8-10. También tiene opciones para que la página de contenido solicite que el iFrame que lo contiene tenga un tamaño determinado y también puede cerrar el iFrame cuando haya terminado.
https://github.com/davidjbradshaw/iframe-resizer
Easy XDM utiliza una colección de trucos para habilitar la comunicación entre dominios entre diferentes ventanas en varios navegadores, y hay ejemplos para usarlo para cambiar el tamaño de iframe:
http://easyxdm.net/wp/2010/03/17/resize-iframe-based-on-content/
http://kinsey.no/blog/index.php/2010/02/19/resizing-iframes-using-easyxdm/
Easy XDM funciona mediante el uso de PostMessage en los navegadores modernos y una solución basada en Flash como respaldo para los navegadores más antiguos.
Vea también este hilo en Stackoverflow (también hay otros, esta es una pregunta común). Además, Facebook parece utilizar un enfoque similar .
Otra opción sería enviar la altura del iframe a su servidor y luego sondear desde ese servidor desde la página web principal con JSONP (o usar una encuesta larga si es posible).
Obtuve la solución para configurar la altura del iframe de forma dinámica en función de su contenido. Esto funciona para el contenido multidominio. Hay algunos pasos a seguir para lograrlo.
Suponga que ha agregado un iframe en la página web "abc.com/page"
<div>
<iframe id="IframeId" src="http://xyz.pqr/contactpage" style="width:100%;" onload="setIframeHeight(this)"></iframe>
</div>
A continuación, debe vincular el evento "mensaje" de Windows en la página web "abc.com/page"
window.addEventListener('message', function (event) {
//Here We have to check content of the message event for safety purpose
//event data contains message sent from page added in iframe as shown in step 3
if (event.data.hasOwnProperty("FrameHeight")) {
//Set height of the Iframe
$("#IframeId").css("height", event.data.FrameHeight);
}
});
En la carga del iframe, debe enviar un mensaje al contenido de la ventana del iframe con el mensaje "FrameHeight":
function setIframeHeight(ifrm) {
var height = ifrm.contentWindow.postMessage("FrameHeight", "*");
}
window.addEventListener('message', function (event) {
// Need to check for safety as we are going to process only our messages
// So Check whether event with data(which contains any object) contains our message here its "FrameHeight"
if (event.data == "FrameHeight") {
//event.source contains parent page window object
//which we are going to use to send message back to main page here "abc.com/page"
//parentSourceWindow = event.source;
//Calculate the maximum height of the page
var body = document.body, html = document.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
// Send height back to parent page "abc.com/page"
event.source.postMessage({ "FrameHeight": height }, "*");
}
});
Lo que hice fue comparar el iframe scrollWidth hasta que cambió de tamaño mientras establecía de forma incremental la altura del iframe. Y funcionó bien para mí. Puede ajustar el incremento a lo que desee.
<script type="text/javascript">
function AdjustIFrame(id) {
var frame = document.getElementById(id);
var maxW = frame.scrollWidth;
var minW = maxW;
var FrameH = 100; //IFrame starting height
frame.style.height = FrameH + "px"
while (minW == maxW) {
FrameH = FrameH + 100; //Increment
frame.style.height = FrameH + "px";
minW = frame.scrollWidth;
}
}
</script>
<iframe id="RefFrame" onload="AdjustIFrame('RefFrame');" class="RefFrame"
src="http://www.YourUrl.com"></iframe>
Tengo un script que cae en el iframe con su contenido. También se asegura de que exista iFrameResizer (lo inyecta como un script) y luego realiza el cambio de tamaño.
Incluiré un ejemplo simplificado a continuación.
// /js/embed-iframe-content.js
(function(){
// Note the id, we need to set this correctly on the script tag responsible for
// requesting this file.
var me = document.getElementById('my-iframe-content-loader-script-tag');
function loadIFrame() {
var ifrm = document.createElement('iframe');
ifrm.id = 'my-iframe-identifier';
ifrm.setAttribute('src', 'http://www.google.com');
ifrm.style.width = '100%';
ifrm.style.border = 0;
// we initially hide the iframe to avoid seeing the iframe resizing
ifrm.style.opacity = 0;
ifrm.onload = function () {
// this will resize our iframe
iFrameResize({ log: true }, '#my-iframe-identifier');
// make our iframe visible
ifrm.style.opacity = 1;
};
me.insertAdjacentElement('afterend', ifrm);
}
if (!window.iFrameResize) {
// We first need to ensure we inject the js required to resize our iframe.
var resizerScriptTag = document.createElement('script');
resizerScriptTag.type = 'text/javascript';
// IMPORTANT: insert the script tag before attaching the onload and setting the src.
me.insertAdjacentElement('afterend', ifrm);
// IMPORTANT: attach the onload before setting the src.
resizerScriptTag.onload = loadIFrame;
// This a CDN resource to get the iFrameResizer code.
// NOTE: You must have the below "coupled" script hosted by the content that
// is loaded within the iframe:
// https://unpkg.com/iframe-resizer@3.5.14/js/iframeResizer.contentWindow.min.js
resizerScriptTag.src = 'https://unpkg.com/iframe-resizer@3.5.14/js/iframeResizer.min.js';
} else {
// Cool, the iFrameResizer exists so we can just load our iframe.
loadIFrame();
}
}())
Luego, el contenido del iframe se puede inyectar en cualquier lugar dentro de otra página / sitio usando el script así:
<script
id="my-iframe-content-loader-script-tag"
type="text/javascript"
src="/js/embed-iframe-content.js"
></script>
El contenido del iframe se inyectará debajo donde coloque la etiqueta de secuencia de comandos.
Espero que esto sea útil para alguien. 👍
<script ... data-src="http://google.com">
y llené el iframe src con él.
iframe-resizer@4.2.10
Aquí está mi solución simple en esta página. http://lab.ohshiftlabs.com/iframesize/
Así es como funciona;
Básicamente, si puede editar la página en otro dominio, puede colocar otra página iframe que pertenezca a su servidor, lo que ahorra altura para las cookies. Con un intervalo de lectura de cookies cuando se actualiza, actualiza la altura del iframe. Eso es todo.
Descargar; http://lab.ohshiftlabs.com/iframesize/iframesizepost.zip
Edición: diciembre de 2019
Básicamente, la solución anterior utiliza otro iframe dentro de un iframe. Pero no es una buena solución, por lo que debe seguir esta:
En la página principal:
window.addEventListener("message", (m)=>{iframeResizingFunction(m)});
Aquí puedes comprobar m.origin
de dónde viene.
En la página del marco:
window.parent.postMessage({ width: 640, height:480 }, "*")
Aunque, no olvide que esta no es una forma tan segura. Para hacerlo seguro, actualice * valor (targetOrigin) con el valor deseado. Siga la documentación: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
Encontré otra solución del lado del servidor para desarrolladores web que usan PHP para obtener el tamaño de un iframe.
Primero está usando el script PHP del servidor para una llamada externa a través de una función interna: (como file_get_contents
con pero curl y dom).
function curl_get_file_contents($url,$proxyActivation=false) {
global $proxy;
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7");
curl_setopt($c, CURLOPT_REFERER, $url);
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
if($proxyActivation) {
curl_setopt($c, CURLOPT_PROXY, $proxy);
}
$contents = curl_exec($c);
curl_close($c);
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
@$dom->loadHTML($contents);
$form = $dom->getElementsByTagName("body")->item(0);
if ($contents) //si on a du contenu
return $dom->saveHTML();
else
return FALSE;
}
$url = "http://www.google.com"; //Exernal url test to iframe
<html>
<head>
<script type="text/javascript">
</script>
<style type="text/css">
#iframe_reserve {
width: 560px;
height: 228px
}
</style>
</head>
<body>
<div id="iframe_reserve"><?php echo curl_get_file_contents($url); ?></div>
<iframe id="myiframe" src="http://www.google.com" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" style="overflow:none; width:100%; display:none"></iframe>
<script type="text/javascript">
window.onload = function(){
document.getElementById("iframe_reserve").style.display = "block";
var divHeight = document.getElementById("iframe_reserve").clientHeight;
document.getElementById("iframe_reserve").style.display = "none";
document.getElementById("myiframe").style.display = "block";
document.getElementById("myiframe").style.height = divHeight;
alert(divHeight);
};
</script>
</body>
</html>
Necesita mostrar debajo de div ( iframe_reserve
) el html generado por la llamada a la función usando un simpleecho curl_get_file_contents("location url iframe","activation proxy")
Después de hacer esto, una función de evento de cuerpo onload con javascript toma la altura del iframe de la página solo con un simple control del contenido div ( iframe_reserve
)
Así que solía divHeight = document.getElementById("iframe_reserve").clientHeight;
obtener la altura de la página externa a la que vamos a llamar después de enmascarar el contenedor div ( iframe_reserve
). Después de esto cargamos el iframe con su buena altura eso es todo.
Me encontré con este problema mientras trabajaba en algo en el trabajo (usando React). Básicamente, tenemos contenido html externo que guardamos en nuestra tabla de documentos en la base de datos y luego insertamos en la página bajo ciertas circunstancias cuando estás en el conjunto de datos de Documentos.
Entonces, dadas las n
líneas, de las cuales hasta n
podrían contener html externo, necesitábamos diseñar un sistema para cambiar automáticamente el tamaño del iframe de cada línea una vez que el contenido esté completamente cargado en cada una. Después de girar un poco mis ruedas, así es como terminé haciéndolo:
message
detector de eventos en el índice de nuestra aplicación React que verifique una clave específica que estableceremos desde el iframe del remitente.<script>
etiqueta que esperará a que se activen los iframe window.onload
. Una vez que se activa, usamos postMessage
para enviar un mensaje a la ventana principal con información sobre la identificación del iframe, la altura calculada, etc.id
del iframe que le pasamos al MessageEvent
objetoiframe
, simplemente establezca la altura del valor que se pasa desde el iframe postMessage
.// index
if (window.postMessage) {
window.addEventListener("message", (messageEvent) => {
if (
messageEvent.data.origin &&
messageEvent.data.origin === "company-name-iframe"
) {
const iframe = document.getElementById(messageEvent.data.id)
// this is the only way to ensure that the height of the iframe container matches its body height
iframe.style.height = `${messageEvent.data.height}px`
// by default, the iframe will not expand to fill the width of its parent
iframe.style.width = "100%"
// the iframe should take precedence over all pointer events of its immediate parent
// (you can still click around the iframe to segue, for example, but all content of the iframe
// will act like it has been directly inserted into the DOM)
iframe.style.pointerEvents = "all"
// by default, iframes have an ugly web-1.0 border
iframe.style.border = "none"
}
})
}
// in component that renders n iframes
<iframe
id={`${props.id}-iframe`}
src={(() => {
const html = [`data:text/html,${encodeURIComponent(props.thirdLineData)}`]
if (window.parent.postMessage) {
html.push(
`
<script>
window.onload = function(event) {
window.parent.postMessage(
{
height: document.body.scrollHeight,
id: "${props.id}-iframe",
origin: "company-name-iframe",
},
"${window.location.origin}"
);
};
</script>
`
)
}
return html.join("\n")
})()}
onLoad={(event) => {
// if the browser does not enforce a cross-origin policy,
// then just access the height directly instead
try {
const { target } = event
const contentDocument = (
target.contentDocument ||
// Earlier versions of IE or IE8+ where !DOCTYPE is not specified
target.contentWindow.document
)
if (contentDocument) {
target.style.height = `${contentDocument.body.scrollHeight}px`
}
} catch (error) {
const expectedError = (
`Blocked a frame with origin "${window.location.origin}" ` +
`from accessing a cross-origin frame.`
)
if (error.message !== expectedError) {
/* eslint-disable no-console */
console.err(
`An error (${error.message}) ocurred while trying to check to see ` +
"if the inner iframe is accessible or not depending " +
"on the browser cross-origin policy"
)
}
}
}}
/>