Ridimensiona l’altezza iframe in base all’altezza del contenuto

Sto aprendo la mia pagina del blog nel mio sito web. Il problema è che posso dare una larghezza ad un iframe ma l’altezza dovrebbe essere dynamic in modo che non ci sia una barra di scorrimento nell’iframe, e sembra una singola pagina …

Ho provato vari codici JavaScript per calcolare l’altezza del contenuto, ma tutti loro danno un errore di accesso negato e non sono utili.

 

Possiamo usare Ajax per calcolare l’altezza o magari usare PHP?

Per rispondere direttamente alle tue due sottoquestioni: No, non puoi farlo con Ajax, né puoi calcolarlo con PHP.

Quello che ho fatto in passato è usare un trigger dalla pagina iframe in window.onload (NON domready , dato che può richiedere un po ‘di tempo per caricare le immagini) per passare all’altezza del corpo della pagina rispetto al genitore.

  

Quindi parent.resizeIframe il parent.resizeIframe aspetto:

 function resizeIframe(newHeight) { document.getElementById('blogIframe').style.height = parseInt(newHeight,10) + 10 + 'px'; } 

Et voilà, hai un robusto resizer che si innesca quando la pagina è completamente renderizzata senza brutto contentdocument vs contentWindow 🙂

Certo, ora la gente vedrà prima il tuo iframe all’altezza predefinita, ma questo può essere facilmente gestito nascondendo l’iframe all’inizio e mostrando solo un’immagine di ‘caricamento’. Quindi, quando resizeIframe funzione la funzione resizeIframe , inserisci due linee extra che nasconderanno l’immagine di caricamento e mostreranno l’iframe per quel look faux Ajax.

Naturalmente, questo funziona solo dallo stesso dominio, quindi potresti voler avere uno script PHP proxy per incorporare questa roba, e una volta che vai lì, potresti anche incorporare il feed RSS del tuo blog direttamente nel tuo sito con PHP.

Puoi farlo con JavaScript.

 document.getElementById('foo').height = document.getElementById('foo').contentWindow.document.body.scrollHeight + "px"; 

L’adattamento dei contenuti IFRAME è una cosa facile da trovare su Google . Ecco una soluzione :

  

Questo naturalmente non risolve il problema interdominio che stai riscontrando … L’impostazione di document.domain può aiutare se questi siti si trovano nello stesso posto. Non penso che ci sia una soluzione se sei iframe di siti casuali.

Ecco la mia soluzione al problema usando MooTools che funziona in Firefox 3.6, Safari 4.0.4 e Internet Explorer 7:

 var iframe_container = $('iframe_container_id'); var iframe_style = { height: 300, width: '100%' }; if (!Browser.Engine.trident) { // IE has hasLayout issues if iframe display is none, so don't use the loading class iframe_container.addClass('loading'); iframe_style.display = 'none'; } this.iframe = new IFrame({ frameBorder: 0, src: "http://www.youriframeurl.com/", styles: iframe_style, events: { 'load': function() { var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document; var h = this.measure(function(){ return innerDoc.body.scrollHeight; }); this.setStyles({ height: h.toInt(), display: 'block' }); if (!Browser.Engine.trident) { iframe_container.removeClass('loading'); } } } }).inject(iframe_container); 

Modella la class “loading” per mostrare un grafico di caricamento Ajax nel mezzo del contenitore iframe. Quindi, per i browser diversi da Internet Explorer, visualizzerà l’altezza completa IFRAME una volta completato il caricamento del suo contenuto e rimuoverà il grafico di caricamento.

Di seguito è il mio gestore di eventi onload .

Io uso un IFRAME all’interno di una finestra di dialogo dell’interfaccia utente jQuery . Usi diversi avranno bisogno di alcuni aggiustamenti. Questo sembra fare il trucco per me (per ora) in Internet Explorer 8 e Firefox 3.5. Potrebbe essere necessario qualche ritouch aggiuntivo, ma l’idea generale dovrebbe essere chiara.

  function onLoadDialog(frame) { try { var body = frame.contentDocument.body; var $body = $(body); var $frame = $(frame); var contentDiv = frame.parentNode; var $contentDiv = $(contentDiv); var savedShow = $contentDiv.dialog('option', 'show'); var position = $contentDiv.dialog('option', 'position'); // disable show effect to enable re-positioning (UI bug?) $contentDiv.dialog('option', 'show', null); // show dialog, otherwise sizing won't work $contentDiv.dialog('open'); // Maximize frame width in order to determine minimal scrollHeight $frame.css('width', $contentDiv.dialog('option', 'maxWidth') - contentDiv.offsetWidth + frame.offsetWidth); var minScrollHeight = body.scrollHeight; var maxWidth = body.offsetWidth; var minWidth = 0; // decrease frame width until scrollHeight starts to grow (wrapping) while (Math.abs(maxWidth - minWidth) > 10) { var width = minWidth + Math.ceil((maxWidth - minWidth) / 2); $body.css('width', width); if (body.scrollHeight > minScrollHeight) { minWidth = width; } else { maxWidth = width; } } $frame.css('width', maxWidth); // use maximum height to avoid vertical scrollbar (if possible) var maxHeight = $contentDiv.dialog('option', 'maxHeight') $frame.css('height', maxHeight); $body.css('width', ''); // correct for vertical scrollbar (if necessary) while (body.clientWidth < maxWidth) { $frame.css('width', maxWidth + (maxWidth - body.clientWidth)); } var minScrollWidth = body.scrollWidth; var minHeight = Math.min(minScrollHeight, maxHeight); // descrease frame height until scrollWidth decreases (wrapping) while (Math.abs(maxHeight - minHeight) > 10) { var height = minHeight + Math.ceil((maxHeight - minHeight) / 2); $body.css('height', height); if (body.scrollWidth < minScrollWidth) { minHeight = height; } else { maxHeight = height; } } $frame.css('height', maxHeight); $body.css('height', ''); // reset widths to 'auto' where possible $contentDiv.css('width', 'auto'); $contentDiv.css('height', 'auto'); $contentDiv.dialog('option', 'width', 'auto'); // re-position the dialog $contentDiv.dialog('option', 'position', position); // hide dialog $contentDiv.dialog('close'); // restore show effect $contentDiv.dialog('option', 'show', savedShow); // open using show effect $contentDiv.dialog('open'); // remove show effect for consecutive requests $contentDiv.dialog('option', 'show', null); return; } //An error is raised if the IFrame domain != its container's domain catch (e) { window.status = 'Error: ' + e.number + '; ' + e.description; alert('Error: ' + e.number + '; ' + e.description); } }; 

Come regolare dynamicmente l’altezza di un iframe è davvero semplice e testato da me.

@ La risposta di SchizoDuckie è molto elegante e leggera, ma a causa della mancanza di implementazione di Webkit per scrollHeight (vedi qui ), non funziona sui browser basati su Webkit (Safari, Chrome, varie e varie piattaforms mobili).

Affinché questa idea di base funzioni su Webkit insieme ai browser Gecko e Trident, è sufficiente sostituirla

  

con

  

Finché tutto è nello stesso dominio, funziona abbastanza bene.

Ho appena trascorso la parte migliore di 3 giorni di lotta con questo. Sto lavorando a un’applicazione che carica altre applicazioni su se stessa mantenendo un’intestazione fissa e un piè di pagina fisso. Ecco cosa mi è venuto in mente. (Ho anche utilizzato EasyXDM, con successo, ma l’ho estratto in seguito per utilizzare questa soluzione.)

Assicurati di eseguire questo codice DOPO che esiste nel DOM. Inseriscilo nella pagina che attira l’iframe (il genitore).

 // get the iframe var theFrame = $("#myIframe"); // set its height to the height of the window minus the combined height of fixed header and footer theFrame.height(Number($(window).height()) - 80); function resizeIframe() { theFrame.height(Number($(window).height()) - 80); } // setup a resize method to fire off resizeIframe. // use timeout to filter out unnecessary firing. var TO = false; $(window).resize(function() { if (TO !== false) clearTimeout(TO); TO = setTimeout(resizeIframe, 500); //500 is time in miliseconds }); 

Il trucco è acquisire tutti gli eventi iframe necessari da uno script esterno. Ad esempio, hai uno script che crea l’iFrame usando document.createElement; in questo stesso script hai temporaneamente accesso ai contenuti di iFrame.

 var dFrame = document.createElement("iframe"); dFrame.src = "http://www.example.com"; // Acquire onload and resize the iframe dFrame.onload = function() { // Setting the content window's resize function tells us when we've changed the height of the internal document // It also only needs to do what onload does, so just have it call onload dFrame.contentWindow.onresize = function() { dFrame.onload() }; dFrame.style.height = dFrame.contentWindow.document.body.scrollHeight + "px"; } window.onresize = function() { dFrame.onload(); } 

Ciò funziona perché dFrame rimane nell’ambito di applicazione in tali funzioni, consentendo l’accesso all’elemento iFrame esterno dall’ambito del frame, consentendo di visualizzare l’altezza del documento effettivo ed espanderlo secondo necessità. Questo esempio funzionerà con Firefox ma da nessun’altra parte; Potrei darti i workaround, ma puoi capire il resto;)

Prova questo, puoi cambiare anche quando vuoi. questo esempio usa jQuery.

 $('#iframe').live('mousemove', function (event) { var theFrame = $(this, parent.document.body); this.height($(document.body).height() - 350); }); 

Prova a usare scrolling=no attributo sul tag iframe. Mozilla ha anche una proprietà CSS overflow-x e overflow-y che puoi esaminare.

In termini di altezza, puoi anche provare l’ height=100% sul tag iframe.