522 Stimmen

Größenänderung eines iframe basierend auf dem Inhalt

Ich arbeite an einer iGoogle-ähnlichen Anwendung. Inhalte aus anderen Anwendungen (auf anderen Domains) werden über iframes angezeigt.

Wie kann ich die Größe der iframes an die Höhe des Inhalts der iframes anpassen?

Ich habe versucht, das von Google verwendete Javascript zu entschlüsseln, aber es ist verschlüsselt, und die Suche im Internet war bisher erfolglos.

Aktualisierung: Bitte beachten Sie, dass die Inhalte von anderen Domains geladen werden, so dass die Politik der gleichen Herkunft gilt.

597voto

ConroyP Punkte 39832

Wir hatten diese Art von Problem, allerdings in umgekehrter Form zu Ihrer Situation - wir stellten die iframed-Inhalte für Websites auf anderen Domänen bereit, so dass die Politik des gleichen Ursprungs war auch ein Thema. Nach vielen Stunden, die wir mit Google verbracht haben, haben wir schließlich eine (einigermaßen ) praktikable Lösung gefunden, die Sie vielleicht an Ihre Bedürfnisse anpassen können.

Es gibt einen Weg, um die gleiche Herkunftsrichtlinie zu umgehen, aber das erfordert Änderungen sowohl an den eingerahmten Inhalten als auch an der Framing-Seite. Wenn Sie also nicht die Möglichkeit haben, Änderungen auf beiden Seiten anzufordern, ist diese Methode leider nicht sehr nützlich für Sie.

Es gibt eine Browser-Merkwürdigkeit, die es uns erlaubt, dieselbe Herkunftspolitik zu umgehen - Javascript kann entweder mit Seiten auf seiner eigenen Domain oder mit Seiten, die es eingerahmt hat, kommunizieren, aber niemals mit Seiten, in denen es eingerahmt ist, z.B. wenn Sie es haben:

 www.foo.com/home.html, which iframes
 |-> www.bar.net/framed.html, which iframes
     |-> www.foo.com/helper.html

entonces home.html kann kommunizieren mit framed.html (iframed) und helper.html (gleiche Domäne).

 Communication options for each page:
 +-------------------------+-----------+-------------+-------------+
 |                         | home.html | framed.html | helper.html |
 +-------------------------+-----------+-------------+-------------+
 | www.foo.com/home.html   |    N/A    |     YES     |     YES     |
 | www.bar.net/framed.html |    NO     |     N/A     |     YES     |
 | www.foo.com/helper.html |    YES    |     YES     |     N/A     |
 +-------------------------+-----------+-------------+-------------+

framed.html kann Nachrichten senden an helper.html (iframed) aber no home.html (das Kind kann nicht domänenübergreifend mit dem Elternteil kommunizieren).

Der Schlüssel dazu ist, dass helper.html kann Nachrichten empfangen von framed.html et kann auch kommunizieren con home.html .

Im Wesentlichen also, wenn framed.html lädt, errechnet er seine eigene Höhe, sagt helper.html der die Nachricht weiterleitet an home.html die dann die Größe des iframe ändern kann, in dem framed.html sits.

Der einfachste Weg, der gefunden wurde, um Nachrichten von framed.html a helper.html war durch ein URL-Argument. Um dies zu tun, framed.html hat einen iframe mit src='' festgelegt. Wenn seine onload ausgelöst wird, wertet er seine eigene Höhe aus und setzt die src des iframe an diesem Punkt auf helper.html?height=N

Hier finden Sie eine Erklärung wie Facebook es handhabt, die vielleicht etwas klarer ist als meine oben!


Code

En www.foo.com/home.html wird der folgende Javascript-Code benötigt (dieser kann übrigens von einer .js-Datei auf einer beliebigen Domain geladen werden):

<script>
  // Resize iframe to full height
  function resizeIframe(height)
  {
    // "+60" is a general rule of thumb to allow for differences in
    // IE & and FF height reporting, can be adjusted as required..
    document.getElementById('frame_name_here').height = parseInt(height)+60;
  }
</script>
<iframe id='frame_name_here' src='http://www.bar.net/framed.html'></iframe>

En www.bar.net/framed.html :

<body onload="iframeResizePipe()">
<iframe id="helpframe" src='' height='0' width='0' frameborder='0'></iframe>

<script type="text/javascript">
  function iframeResizePipe()
  {
     // What's the page height?
     var height = document.body.scrollHeight;

     // Going to 'pipe' the data to the parent through the helpframe..
     var pipe = document.getElementById('helpframe');

     // Cachebuster a precaution here to stop browser caching interfering
     pipe.src = 'http://www.foo.com/helper.html?height='+height+'&cacheb='+Math.random();

  }
</script>

Inhalt von www.foo.com/helper.html :

<html> 
<!-- 
This page is on the same domain as the parent, so can
communicate with it to order the iframe window resizing
to fit the content 
--> 
  <body onload="parentIframeResize()"> 
    <script> 
      // Tell the parent iframe what height the iframe needs to be
      function parentIframeResize()
      {
         var height = getParam('height');
         // This works as our parent's parent is on our domain..
         parent.parent.resizeIframe(height);
      }

      // Helper function, parse param from request string
      function getParam( name )
      {
        name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
        var regexS = "[\\?&]"+name+"=([^&#]*)";
        var regex = new RegExp( regexS );
        var results = regex.exec( window.location.href );
        if( results == null )
          return "";
        else
          return results[1];
      }
    </script> 
  </body> 
</html>

77voto

Ahmy Punkte 5196

Wenn Sie keinen Iframe-Inhalt von einer anderen Domain behandeln müssen, versuchen Sie diesen Code, er löst das Problem vollständig und ist einfach:

<script language="JavaScript">
<!--
function autoResize(id){
    var newheight;
    var newwidth;

    if(document.getElementById){
        newheight=document.getElementById(id).contentWindow.document .body.scrollHeight;
        newwidth=document.getElementById(id).contentWindow.document .body.scrollWidth;
    }

    document.getElementById(id).height= (newheight) + "px";
    document.getElementById(id).width= (newwidth) + "px";
}
//-->
</script>

<iframe src="usagelogs/default.aspx" width="100%" height="200px" id="iframe1" marginheight="0" frameborder="0" onLoad="autoResize('iframe1');"></iframe>

42voto

Chris Jacob Punkte 11328

https://developer.mozilla.org/en/DOM/window.postMessage

window.postMessage()

window.postMessage ist eine Methode, die eine sichere herkunftsübergreifende Kommunikation ermöglicht. Normalerweise dürfen Skripte auf verschiedenen Seiten nur dann aufeinander zugreifen, wenn sich die Seiten, die sie ausgeführt haben, an Orten befinden, die dasselbe Protokoll (in der Regel http), dieselbe Portnummer (80 ist der Standardwert für http) und denselben Host haben (modulo document.domain wird von beiden Seiten auf denselben Wert gesetzt). window.postMessage bietet einen kontrollierten Mechanismus, um diese Beschränkung auf eine Weise zu umgehen, die bei ordnungsgemäßer Verwendung sicher ist.

Zusammenfassung

window.postMessage bewirkt bei seinem Aufruf, dass ein MessageEvent an das Zielfenster gesendet wird, wenn ein anstehendes Skript, das ausgeführt werden muss, abgeschlossen ist (z. B. verbleibende Ereignishandler, wenn window.postMessage von einem Ereignishandler aufgerufen wird, zuvor eingestellte anstehende Timeouts usw.). Das MessageEvent hat den Typ message, eine data-Eigenschaft, die auf den String-Wert des ersten Arguments von window.postMessage gesetzt wird, eine origin-Eigenschaft, die dem Ursprung des Hauptdokuments in dem Fenster entspricht, das window.postMessage zum Zeitpunkt des Aufrufs von window.postMessage aufruft, und eine source-Eigenschaft, die das Fenster ist, aus dem window.postMessage aufgerufen wird. (Andere Standardeigenschaften von Ereignissen sind mit ihren erwarteten Werten vorhanden).

El iFrame-Resizer Bibliothek verwendet postMessage, um einen iFrame in der Größe seines Inhalts zu halten, zusammen mit MutationObserver um Änderungen am Inhalt zu erkennen und ist nicht auf jQuery angewiesen.

https://github.com/davidjbradshaw/iframe-resizer

jQuery: Domänenübergreifendes Skripting

http://benalman.com/projects/jquery-postmessage-plugin/

Hat Demo der Größenänderung iframe Fenster...

http://benalman.com/code/projects/jquery-postmessage/examples/iframe/

Dieser Artikel zeigt, wie man die Abhängigkeit von jQuery entfernt... Plus hat eine Menge nützlicher Informationen und Links zu anderen Lösungen.

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

Nacktes Beispiel...

http://onlineaspect.com/uploads/postmessage/parent.html

HTML 5 Arbeitsentwurf zu window.postMessage

http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages

John Resig über fensterübergreifende Nachrichtenübermittlung

http://ejohn.org/blog/cross-window-messaging/

8voto

Omer Arshad Punkte 500

Der einfachste Weg ist die Verwendung von jQuery:

$("iframe")
.attr({"scrolling": "no", "src":"http://www.someotherlink.com/"})
.load(function() {
    $(this).css("height", $(this).contents().height() + "px");
});

6voto

Macho Matt Punkte 1246

Die Lösung auf http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html funktioniert hervorragend (verwendet jQuery):

<script type=”text/javascript”>
  $(document).ready(function() {
    var theFrame = $(”#iFrameToAdjust”, parent.document.body);
    theFrame.height($(document.body).height() + 30);
  });
</script>

Ich weiß nicht, ob man 30 zu der Länge addieren muss... 1 hat bei mir funktioniert.

ZU IHRER INFORMATION : Wenn Sie bereits ein "height"-Attribut in Ihrem iFrame haben, wird einfach style="height: xxx" hinzugefügt. Das ist vielleicht nicht das, was Sie wollen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X