Ho provato alcune soluzioni ma non ho avuto successo. Mi chiedo se esista una soluzione preferibilmente con un tutorial facile da seguire.
Ho provato alcune soluzioni ma non ho avuto successo. Mi chiedo se esista una soluzione preferibilmente con un tutorial facile da seguire.
Risposte:
Hai tre alternative:
Questa è una semplice libreria per mantenere gli iFrame dimensionati in base al loro contenuto. Utilizza le API PostMessage e MutationObserver, con fall back per IE8-10. Ha anche opzioni per la pagina dei contenuti per richiedere che l'iFrame contenente sia di una certa dimensione e può anche chiudere l'iFrame quando hai finito.
https://github.com/davidjbradshaw/iframe-resizer
Easy XDM utilizza una raccolta di trucchi per abilitare la comunicazione interdominio tra diverse finestre in diversi browser, e ci sono esempi per utilizzarlo per il ridimensionamento 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 funziona utilizzando PostMessage sui browser moderni e una soluzione basata su Flash come riserva per i browser meno recenti.
Vedi anche questo thread su Stackoverflow (ce ne sono anche altri, questa è una domanda comune). Inoltre, Facebook sembrerebbe utilizzare un approccio simile .
Un'altra opzione potrebbe essere quella di inviare l'altezza dell'iframe al tuo server e quindi eseguire il polling da quel server dalla pagina web principale con JSONP (o utilizzare un sondaggio lungo se possibile).
Ho la soluzione per impostare l'altezza dell'iframe in modo dinamico in base al suo contenuto. Funziona per il contenuto interdominio. Ci sono alcuni passaggi da seguire per raggiungere questo obiettivo.
Supponi di aver aggiunto iframe nella pagina web "abc.com/page"
<div>
<iframe id="IframeId" src="http://xyz.pqr/contactpage" style="width:100%;" onload="setIframeHeight(this)"></iframe>
</div>
Successivamente devi associare l'evento "messaggio" di Windows nella pagina 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);
}
});
Al caricamento dell'iframe devi inviare un messaggio al contenuto della finestra dell'iframe con il messaggio "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 }, "*");
}
});
Quello che ho fatto è stato confrontare l'iframe scrollWidth fino a quando non ha cambiato dimensione mentre ho impostato in modo incrementale l'altezza IFrame. E ha funzionato bene per me. È possibile regolare l'incremento in base alle proprie esigenze.
<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>
Ho uno script che cade nell'iframe con il suo contenuto. Inoltre si assicura che iFrameResizer esista (lo inietta come uno script) e quindi esegue il ridimensionamento.
Farò un esempio semplificato di seguito.
// /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();
}
}())
Quindi il contenuto dell'iframe può essere iniettato ovunque all'interno di un'altra pagina / sito utilizzando lo script in questo modo:
<script
id="my-iframe-content-loader-script-tag"
type="text/javascript"
src="/js/embed-iframe-content.js"
></script>
Il contenuto dell'iframe verrà inserito di seguito ovunque si inserisca il tag script.
Spero che questo sia utile a qualcuno. 👍
<script ... data-src="http://google.com">
e riempito l'iframe src con esso.
iframe-resizer@4.2.10
Ecco la mia semplice soluzione in questa pagina. http://lab.ohshiftlabs.com/iframesize/
Ecco come funziona;
Fondamentalmente se sei in grado di modificare la pagina su un altro dominio puoi inserire un'altra pagina iframe che appartiene al tuo server che risparmia altezza ai cookie. Con un intervallo di lettura dei cookie quando viene aggiornato, aggiorna l'altezza dell'iframe. Questo è tutto.
Scarica; http://lab.ohshiftlabs.com/iframesize/iframesizepost.zip
Modifica: 2019 dicembre
La soluzione sopra utilizza fondamentalmente un altro iframe all'interno di un iframe. Il terzo iframe appartiene al dominio della pagina superiore, che chiami questa pagina con una stringa di query che salva il valore della dimensione in un cookie, la pagina esterna controlla questa query con un certo intervallo. Ma non è una buona soluzione, quindi dovresti seguire questa:
Nella pagina principale:
window.addEventListener("message", (m)=>{iframeResizingFunction(m)});
Qui puoi controllare m.origin
per vedere da dove viene.
Nella pagina frame:
window.parent.postMessage({ width: 640, height:480 }, "*")
Tuttavia, per favore non dimenticare che questo non è un modo così sicuro. Per renderlo sicuro, aggiorna * il valore (targetOrigin) con il valore desiderato. Segui la documentazione: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
Ho trovato un'altra soluzione lato server per lo sviluppo web utilizzando PHP per ottenere le dimensioni di un iframe.
Il primo è usare lo script del server PHP per una chiamata esterna tramite la funzione interna: (come un file_get_contents
with but curl e 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>
È necessario visualizzare sotto div ( iframe_reserve
) l'html generato dalla chiamata di funzione utilizzando un semplice fileecho curl_get_file_contents("location url iframe","activation proxy")
Dopo aver fatto ciò, una funzione di evento del corpo onload con javascript prende l'altezza dell'iframe della pagina solo con un semplice controllo del contenuto div ( iframe_reserve
)
Quindi ho usato divHeight = document.getElementById("iframe_reserve").clientHeight;
per ottenere l'altezza della pagina esterna che chiameremo dopo aver mascherato il contenitore div ( iframe_reserve
). Dopodiché carichiamo l'iframe con la sua buona altezza, tutto qui.
Mi sono imbattuto in questo problema mentre lavoravo su qualcosa al lavoro (usando React). Fondamentalmente, abbiamo del contenuto html esterno che salviamo nella nostra tabella dei documenti nel database e poi inseriamo nella pagina in determinate circostanze quando sei nel set di dati Documenti.
Quindi, dati gli n
inline, di cui fino a n
potevano contenere html esterno, dovevamo ideare un sistema per ridimensionare automaticamente l'iframe di ogni inline una volta che il contenuto era completamente caricato in ciascuno. Dopo aver fatto girare le ruote per un po ', è così che ho finito per farlo:
message
listener di eventi nell'indice della nostra app React che verifica la presenza di una chiave specifica che imposteremo dall'iframe del mittente.<script>
tag che attenderà l'attivazione dell'iframe window.onload
. Una volta che si attiva, usiamo postMessage
per inviare un messaggio alla finestra principale con informazioni sull'id iframe, l'altezza calcolata, ecc.id
dell'iframe che passiamo MessageEvent
nell'oggettoiframe
, imposta l'altezza dal valore passato dall'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"
)
}
}
}}
/>