J'ai essayé quelques solutions mais je n'ai pas réussi. Je me demande s'il existe une solution de préférence avec un tutoriel facile à suivre.
J'ai essayé quelques solutions mais je n'ai pas réussi. Je me demande s'il existe une solution de préférence avec un tutoriel facile à suivre.
Réponses:
Vous avez trois alternatives:
Il s'agit d'une bibliothèque simple pour garder les iFrames dimensionnés en fonction de leur contenu. Il utilise les API PostMessage et MutationObserver, avec des solutions de secours pour IE8-10. Il a également des options pour que la page de contenu demande que l'iFrame contenant soit une certaine taille et peut également fermer l'iFrame lorsque vous en avez terminé.
https://github.com/davidjbradshaw/iframe-resizer
Easy XDM utilise une collection d'astuces pour activer la communication interdomaine entre différentes fenêtres dans un certain nombre de navigateurs, et il existe des exemples d'utilisation pour le redimensionnement 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 fonctionne en utilisant PostMessage sur les navigateurs modernes et une solution basée sur Flash comme solution de secours pour les navigateurs plus anciens.
Voir aussi ce fil sur Stackoverflow (il y en a aussi d'autres, c'est une question fréquemment posée). En outre, Facebook semble utiliser une approche similaire .
Une autre option serait d'envoyer la hauteur de l'iframe à votre serveur, puis d'interroger ce serveur à partir de la page Web parente avec JSONP (ou d'utiliser un long sondage si possible).
J'ai eu la solution pour définir la hauteur de l'iframe de manière dynamique en fonction de son contenu. Cela fonctionne pour le contenu interdomaine. Il y a quelques étapes à suivre pour y parvenir.
Supposons que vous ayez ajouté un iframe dans la page Web "abc.com/page"
<div>
<iframe id="IframeId" src="http://xyz.pqr/contactpage" style="width:100%;" onload="setIframeHeight(this)"></iframe>
</div>
Ensuite, vous devez lier l'événement Windows "message" sous la page 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);
}
});
Lors du chargement d'iframe, vous devez envoyer un message au contenu de la fenêtre iframe avec le message "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 }, "*");
}
});
Ce que j'ai fait, c'est comparer l'iframe scrollWidth jusqu'à ce qu'il change de taille pendant que je règle incrémentalement la hauteur IFrame. Et cela a bien fonctionné pour moi. Vous pouvez ajuster l'incrément à ce que vous souhaitez.
<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>
J'ai un script qui tombe dans l'iframe avec son contenu. Il s'assure également que iFrameResizer existe (il l'injecte en tant que script), puis effectue le redimensionnement.
Je vais vous présenter un exemple simplifié ci-dessous.
// /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();
}
}())
Ensuite, le contenu iframe peut être injecté n'importe où dans une autre page / site en utilisant le script comme suit:
<script
id="my-iframe-content-loader-script-tag"
type="text/javascript"
src="/js/embed-iframe-content.js"
></script>
Le contenu iframe sera injecté ci-dessous où que vous placiez la balise de script.
J'espère que cela est utile à quelqu'un. 👍
<script ... data-src="http://google.com">
et rempli l'iframe src avec.
iframe-resizer@4.2.10
Voici ma solution simple sur cette page. http://lab.ohshiftlabs.com/iframesize/
Voici comment cela fonctionne;
Fondamentalement, si vous pouvez modifier la page sur un autre domaine, vous pouvez placer une autre page iframe qui appartient à votre serveur, ce qui économise de la hauteur aux cookies. Avec un intervalle de lecture des cookies lors de sa mise à jour, mettez à jour la hauteur de l'iframe. C'est tout.
Télécharger; http://lab.ohshiftlabs.com/iframesize/iframesizepost.zip
Edit: décembre 2019
La solution ci-dessus utilise essentiellement une autre iframe à l'intérieur d'un iframe 3ème iframe appartient au domaine de la page supérieure, que vous appelez cette page avec une chaîne de requête qui enregistre la valeur de la taille dans un cookie, la page externe vérifie cette requête avec un certain intervalle. Mais ce n'est pas une bonne solution, vous devez donc suivre celle-ci:
En haut de la page:
window.addEventListener("message", (m)=>{iframeResizingFunction(m)});
Ici, vous pouvez vérifier m.origin
d'où il vient.
Dans la page cadre:
window.parent.postMessage({ width: 640, height:480 }, "*")
Cependant, n'oubliez pas que ce n'est pas un moyen sûr. Pour le rendre sécurisé, mettez à jour la valeur * (targetOrigin) avec la valeur souhaitée. Veuillez suivre la documentation: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
J'ai trouvé une autre solution côté serveur pour les développeurs Web en utilisant PHP pour obtenir la taille d'une iframe.
La première consiste à utiliser le script serveur PHP pour un appel externe via une fonction interne: (comme file_get_contents
avec mais curl et 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>
Vous devez afficher sous le div ( iframe_reserve
) le html généré par l'appel de fonction en utilisant un simpleecho curl_get_file_contents("location url iframe","activation proxy")
Après cela, une fonction d'événement body onload avec javascript prend la hauteur de la page iframe juste avec un simple contrôle du contenu div ( iframe_reserve
)
J'ai donc utilisé divHeight = document.getElementById("iframe_reserve").clientHeight;
pour obtenir la hauteur de la page externe que nous allons appeler après avoir masqué le conteneur div ( iframe_reserve
). Après cela, nous chargeons l'iframe avec sa bonne hauteur c'est tout.
J'ai rencontré ce problème en travaillant sur quelque chose au travail (en utilisant React). Fondamentalement, nous avons du contenu html externe que nous sauvegardons dans notre table de documents dans la base de données, puis insérons sur la page dans certaines circonstances lorsque vous êtes dans l'ensemble de données Documents.
Ainsi, étant donné les n
inlines, dont jusqu'à n
pouvait contenir du html externe, nous devions concevoir un système pour redimensionner automatiquement l'iframe de chaque inline une fois le contenu entièrement chargé dans chacun. Après avoir fait tourner mes roues pendant un moment, voici comment j'ai fini par le faire:
message
écouteur d'événements dans l'index de notre application React qui recherche une clé spécifique que nous définirons à partir de l'iframe de l'expéditeur.<script>
balise qui attendra que l'iframe window.onload
se déclenche. Une fois que cela se déclenche, nous utilisons postMessage
pour envoyer un message à la fenêtre parente avec des informations sur l'identifiant iframe, la hauteur calculée, etc.id
de l'iframe que nous passons dans l' MessageEvent
objetiframe
, définissez simplement la hauteur à partir de la valeur transmise par l'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"
)
}
}
}}
/>