Frage

Ich arbeite an einer iGoogle-ähnliche Anwendung. Inhalte aus anderen Anwendungen (auf anderen Domänen) wird mit iframes gezeigt.

Wie ändere ich die Größe der iframes die Höhe des iframes' Inhalt passen?

Ich habe versucht, die JavaScript verwendet Google zu entziffern, aber es ist verschleiert, und die Web-Suche ergebnislos war so weit.

Update: Bitte beachten Sie, dass Inhalte aus anderen Domänen geladen wird, so dass die same-origin policy gilt.

War es hilfreich?

Lösung

Wir hatten diese Art von Problem, aber etwas in umgekehrter Richtung auf Ihre Situation - wir die IFramed Inhalte auf Websites auf anderen Domänen wurden bereitgestellt, so dass die same origin policy auch ein Thema war. Nach vielen Stunden Schleppen Google verbracht, fanden wir schließlich eine (etwas ..) praktikable Lösung, die Sie an Ihre Bedürfnisse anpassen können in der Lage sein.

Es gibt einen Weg um die gleiche Ursprung Politik, aber es erfordert Änderungen sowohl auf den IFramed Inhalt und die Gestaltung Seite, wenn Sie also nicht die Möglichkeit haben, Änderungen auf beiden Seiten zu verlangen, ist diese Methode nicht sehr nützlich seinen Sie, ich habe Angst.

Es gibt einen Browser Marotte, die uns die gleichen Ursprung Politik Rock erlaubt - Javascript kann entweder kommunizieren mit Seiten auf einer eigenen Domain oder mit Seiten hat Iframes, aber nie Seiten, in denen es eingerahmt wird, beispielsweise wenn Sie:

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

dann kann home.html mit framed.html kommunizieren (Iframes) und helper.html (gleiche Domain).

 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 (Iframes) aber nicht home.html (Kind kann nicht kommunizieren Cross-Domain mit Eltern).

Der Schlüssel hier ist, dass helper.html Nachrichten von framed.html empfangen können, und kann auch kommunizieren mit home.html.

So im Wesentlichen, wenn framed.html Lasten, funktioniert es seine eigene Höhe aus, sagt helper.html, die die Nachricht an home.html gibt, die den iframe dann können die Größe, in der framed.html sitzt.

Die einfachste Art, wie wir Nachrichten gefunden von framed.html zu helper.html passieren war durch ein URL-Argument. Um dies zu tun, hat framed.html einen Iframe mit src='' angegeben. Wenn seine onload Feuer, es seine eigene Höhe auswertet und setzt die src des iframe an dieser Stelle helper.html?height=N

Es gibt eine Erklärung hier , wie Facebook umgehen, die als meine oben etwas klarer sein können!


Code

In www.foo.com/home.html der folgenden JavaScript-Code erforderlich ist (dies aus einer js-Datei auf einem beliebigen Domäne geladen werden kann, nebenbei bemerkt ..):

<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>

In 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>

Der Inhalt 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>

Andere Tipps

Wenn Sie brauchen, um diesen Code nicht iframe Inhalt aus einer anderen Domäne zu umgehen, versuchen Sie, es wird das Problem vollständig zu lösen, und es ist ganz 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>

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

  

window.postMessage ()

     

window.postMessage ist ein Verfahren zum sicheren ermöglicht Cross-Origin-Kommunikation. Normalerweise werden Skripte auf verschiedenen Seiten gegenseitig nur zugreifen dürfen, wenn und nur wenn die Seiten, die sie an Orten mit dem gleichen Protokoll ausgeführt sind (in der Regel sowohl http), die Portnummer (80 der Standard für http sind) und Host (Modulo document.domain wurde von beiden Seiten auf den gleichen Wert gesetzt). window.postMessage stellt eine gesteuerte Mechanismus, um diese Einschränkung in einer Art und Weise zu umgehen, die sicher ist, wenn sie richtig verwendet wird.

     

Zusammenfassung

     

window.postMessage, wenn sie aufgerufen wird, bewirkt, dass ein Message im Zielfenster abgefertigt werden, wenn eine anhängige Skript, das abgeschlossen ist ausgeführt werden muß (zB verbleibende Event-Handler, wenn window.postMessage von einem Event-Handler aufgerufen wird, zuvor eingestellten anstehendes Timeouts , usw.). Der Messagetyp hat die Nachricht eine Daten Eigenschaft, die zu window.postMessage vorgesehen auf den String-Wert des ersten Arguments gesetzt ist, Eigenschaft ein Ursprung auf den Ursprung des Hauptdokuments in dem Fenster entsprechenden window.postMessage im Zeitfenster aufgerufen wird. postmessage genannt wurde, und eine Quelle Eigenschaft, die das Fenster, aus dem window.postMessage genannt wird. (Andere Standardeigenschaften von Ereignissen vorhanden sind mit ihren erwarteten Werten.)

Die iFrame-Resizer Bibliothek verwendet ein iFrame postmessage zu halten so bemessen, dass es Inhalt ist, zusammen mit MutationObserver Änderungen an den Inhalt zu erkennen und hängt nicht von jQuery.

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

jQuery: Quer Domain-Scripting Güte

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

Hat Demo von Ändern der Größe iframe Fenster ...

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

Dieser Artikel zeigt, wie die Abhängigkeit von jQuery entfernen ... Plus hat viele nützliche Informationen und Links zu anderen Lösungen.

http://www.onlineaspect.com/2010/01 / 15 / rückwärtskompatibel-Postmessage /

Barebones Beispiel ...

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

HTML 5 Arbeitsentwurf auf window.postMessage

http: //www.whatwg. org / specs / web-apps / Strom-Arbeit / Mehrseiten- / comms.html # crossDocumentMessages

John Resig on Cross-Fenster Messaging

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

Der einfachste Weg, mit jQuery:

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

Die Lösung auf http: // www. phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html große Werke (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, dass Sie 30 die Länge hinzufügen müssen ... 1 für mich gearbeitet.

FYI : Wenn Sie bereits ein "Höhe" Attribut auf Ihrem iFrame haben, das kommt noch hinzu, style = "height: xxx". Dies könnte nicht das sein, was Sie wollen.

kann ein bisschen spät sein, da alle anderen Antworten älter :-) sind aber ... Heres meine Lösung. Geprüft tatsächliche FF, Chrome und Safari 5.0.

CSS:

iframe {border:0; overflow:hidden;}

javascript:

$(document).ready(function(){
    $("iframe").load( function () {
        var c = (this.contentWindow || this.contentDocument);
        if (c.document) d = c.document;
        var ih = $(d).outerHeight();
        var iw = $(d).outerWidth();
        $(this).css({
            height: ih,
            width: iw
        });
    });
});

Hope dies jemand helfen.

Schließlich fand ich eine andere Lösung für die Datenmutter Website von iframe window.postMessage(message, targetOrigin); senden. Hier erkläre ich, wie ich es tat.

Site A = http://foo.com Standort B = http://bar.com

SiteB ist in der SITEA Webseite laden

SiteB Website hat diese Zeile

window.parent.postMessage("Hello From IFrame", "*"); 

oder

window.parent.postMessage("Hello From IFrame", "http://foo.com");

Dann diesen folgenden Code SITEA haben

// Here "addEventListener" is for standards-compliant web browsers and "attachEvent" is for IE Browsers.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];


var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen to message from child IFrame window
eventer(messageEvent, function (e) {
   alert(e.data);
   // Do whatever you want to do with the data got from IFrame in Parent form.
}, false); 

Wenn Sie die Sicherheit Verbindung hinzufügen möchten, können Sie diese verwenden, wenn die Bedingung in eventer(messageEvent, function (e) {})

if (e.origin == 'http://iframe.example.com') {
    alert(e.data); 
    // Do whatever you want to do with the data got from IFrame in Parent form.
}

Für IE

Innerhalb IFrame:

 window.parent.postMessage('{"key":"value"}','*');

Außenbereich:

 eventer(messageEvent, function (e) {
   var data = jQuery.parseJSON(e.data);
   doSomething(data.key);
 }, false);

Hier ist eine einfache Lösung, die eine dynamisch generierte Stylesheet serviert von dem gleichen Server wie der iframe Inhalt verwenden. Ganz einfach das Stylesheet „weiß“, was in der iframe ist, und kennt die Dimensionen zu verwenden, um den iframe zu stylen. Dies wird um den gleichen Ursprung Politik Einschränkungen.

http://www.8degrees.co.nz/2010/06/09/dynamically-resize-an-iframe-depending-on-its-content/

, kann der gelieferte iframe Code würde wie so ein begleitendes Stylesheet hat ...

<link href="http://your.site/path/to/css?contents_id=1234&dom_id=iframe_widget" rel="stylesheet" type="text/css" />
 <iframe id="iframe_widget" src="http://your.site/path/to/content?content_id=1234" frameborder="0" width="100%" scrolling="no"></iframe>

Dies funktioniert die serverseitige Logik erfordern in der Lage, die Dimensionen des gerenderten Inhalt des iframe zu berechnen.

Diese Antwort ist nur für Websites, die Bootstrap verwendet. Das ansprechende einbetten Merkmal der Bootstrap macht die Arbeit. Es basiert auf der Breite (nicht Höhe) des Inhalts.

<!-- 16:9 aspect ratio -->
<div class="embed-responsive embed-responsive-16by9">
  <iframe class="embed-responsive-item" src="http://www.youtube.com/embed/WsFWhL4Y84Y"></iframe>
</div>

jsfiddle: http://jsfiddle.net/00qggsjj/2/

http://getbootstrap.com/components/#responsive-embed

Ich bin die Umsetzung ConroyP-Rahmen-in-Rahmen-Lösung eine Lösung auf Einstellung document.domain Basis zu ersetzen, aber fand es ziemlich schwer werden, um die Höhe des iframe Inhalts Bestimmung richtig in verschiedenen Browsern (Prüfung mit FF11, Ch17 und IE9 jetzt).

ConroyP verwendet:

var height = document.body.scrollHeight;

Aber das nur auf der Anfangsseite Last arbeitet. Mein iframe hat dynamischen Inhalt und ich brauche die iframe auf bestimmte Ereignisse zu ändern.

Was ich am Ende dabei wurde unter Verwendung verschiedene JS Eigenschaften für die verschiedenen Browser.

function getDim () {
    var body = document.body,
        html = document.documentElement;

    var bc = body.clientHeight;
    var bo = body.offsetHeight;
    var bs = body.scrollHeight;
    var hc = html.clientHeight;
    var ho = html.offsetHeight;
    var hs = html.scrollHeight;

    var h = Math.max(bc, bo, bs, hc, hs, ho);

    var bd = getBrowserData();

    // Select height property to use depending on browser
    if (bd.isGecko) {
        // FF 11
        h = hc;
    } else if (bd.isChrome) {
        // CH 17
        h = hc;
    } else if (bd.isIE) {
        // IE 9
        h = bs;
    }

    return h;
}

getBrowserData () ist eine Funktion Browser erkennen "inspiriert" von Ext Core http://docs.sencha.com/core/source/Ext.html#method-Ext-apply

Das ist gut funktionierte für FF und IE, aber dann gibt es Probleme mit Chrome. Einer der war ein Timing-Problem, es anscheinend Chrome eine Weile dauert, die Höhe des iframe zu setzen / erkennen. Und dann Chrome auch nie wieder die Höhe des Inhalts in der iframe korrekt, wenn der iframe höher ist als der Inhalt war. Dies wäre nicht mit dynamischen Inhalten arbeiten, wenn die Höhe reduziert wird.

Um dies zu lösen ich die iframe auf eine niedrige Höhe immer gesetzt, bevor der Inhalt der Höhe zu erfassen und dann die iframe Höheneinstellung, um es korrekten Wert ist.

function resize () {
    // Reset the iframes height to a low value.
    // Otherwise Chrome won't detect the content height of the iframe.
    setIframeHeight(150);

    // Delay getting the dimensions because Chrome needs
    // a few moments to get the correct height.
    setTimeout("getDimAndResize()", 100);
}

Der Code nicht optimiert ist, ist es aus meinem Entwick Test:)

Hope jemand findet diese hilfreich!

<html>
<head>
<script>
function frameSize(id){
var frameHeight;

document.getElementById(id).height=0 + "px";
if(document.getElementById){
    newheight=document.getElementById(id).contentWindow.document.body.scrollHeight;    
}

document.getElementById(id).height= (frameHeight) + "px";
}
</script>
</head>

<body>

<iframe id="frame"  src="startframe.html" frameborder="0" marginheight="0" hspace=20     width="100%" 

onload="javascript:frameSize('frame');">

<p>This will work, but you need to host it on an http server, you can do it locally.    </p>
</body>
</html>

iGoogle-Gadgets haben aktiv zu implementieren Ändern der Größe, so meine Vermutung ist, in einem Cross-Domain-Modell können Sie dies nicht ohne die Remote-Inhalt tun in irgendeiner Weise teilnehmen. Wenn Ihr Inhalt eine Nachricht mit der neuen Größe an die Containerseite mit typischen Cross-Domain-Kommunikationstechniken senden kann, dann der Rest ist einfach.

Wenn Sie eine Web-Seite verkleinern es in die iframe Größe zu passen:

  1. Sie sollten die iframe die Größe es mit dem Inhalt passen
  2. Dann sollten Sie die ganze iframe mit dem geladenen Webseite Inhalt
  3. Verkleinern

Hier ist ein Beispiel:

<div id="wrap">
   <IFRAME ID="frame" name="Main" src ="http://www.google.com" />
</div>

<style type="text/css">
    #wrap { width: 130px; height: 130px; padding: 0; overflow: hidden; }
    #frame { width: 900px; height: 600px; border: 1px solid black; }
    #frame { zoom:0.15; -moz-transform:scale(0.15);-moz-transform-origin: 0 0; }
</style>

Hier ist ein jQuery-Ansatz, der die Informationen in json über das src-Attribut des iframe erstellt. Hier ist eine Demo, die Größe und das Fenster bewegen .. die resultierende URL mit json wie folgt aussieht ... http: // Geige. jshell.net/zippyskippy/RJN3G/show/#{docHeight:5124,windowHeight:1019,scrollHeight:571}#

Hier ist der Quellcode Geige http://jsfiddle.net/zippyskippy/RJN3G/

function updateLocation(){

    var loc = window.location.href;
    window.location.href = loc.replace(/#{.*}#/,"") 
        + "#{docHeight:"+$(document).height() 
        + ",windowHeight:"+$(window).height()
        + ",scrollHeight:"+$(window).scrollTop()
        +"}#";

};

//setInterval(updateLocation,500);

$(window).resize(updateLocation);
$(window).scroll(updateLocation);

get iframe Inhalt Höhe es dann zu dieser iframe geben

 var iframes = document.getElementsByTagName("iframe");
 for(var i = 0, len = iframes.length; i<len; i++){
      window.frames[i].onload = function(_i){
           return function(){
                     iframes[_i].style.height = window.frames[_i].document.body.scrollHeight + "px";
                     }
      }(i);
 }

Arbeiten mit jquery auf Last (Cross-Browser):

 <iframe src="your_url" marginwidth="0"  marginheight="0" scrolling="No" frameborder="0"  hspace="0" vspace="0" id="containiframe" onload="loaderIframe();" height="100%"  width="100%"></iframe>

function loaderIframe(){
var heightIframe = $('#containiframe').contents().find('body').height();
$('#frame').css("height", heightFrame);
 }  

auf Resize in ansprechbar Seite:

$(window).resize(function(){
if($('#containiframe').length !== 0) {
var heightIframe = $('#containiframe').contents().find('body').height();
 $('#frame').css("height", heightFrame);
}
});

Mit jQuery:

Parent.html

<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<style>
iframe {
    width: 100%;
    border: 1px solid black;
}
</style>
<script>
function foo(w, h) {
    $("iframe").css({width: w, height: h});
    return true;  // for debug purposes
}
</script>
<iframe src="child.html"></iframe>
</body>

child.html

<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(function() {
    var w = $("#container").css("width");
    var h = $("#container").css("height");

    var req = parent.foo(w, h);
    console.log(req); // for debug purposes
});
</script>
<style>
body, html {
    margin: 0;
}
#container {
    width: 500px;
    height: 500px;
    background-color: red;
}
</style>
<div id="container"></div>
</body>

Das ist etwas schwierig, weil Sie wissen müssen, wenn die iframe-Seite geladen ist, die difficuly ist, wenn Sie nicht in der Kontrolle ihres Inhalts sind. Es ist möglich, einen onload-Handler zum iframe hinzuzufügen, aber ich habe dies in der Vergangenheit versucht, und es hat sehr unterschiedliches Verhalten in alle Browsern (nicht erraten, wer die nervigste ist ...). Sie würden vermutlich eine Funktion für die iframe Seite hinzufügen müssen, die die Größe ändern und injizieren ein Skript in den Inhalt führt, die entweder hört Ereignisse zu laden oder Ereignisse die Größe, die dann die vorherige Funktion aufruft. Ich denke, eine Funktion zur Seite hinzufügen, da Sie sicher, dass sein sicherer machen wollen, aber ich habe keine Ahnung, wie einfach es sein wird zu tun.

Etwas auf den Linien von dieser i arbeiten glauben soll.

parent.document.getElementById(iFrameID).style.height=framedPage.scrollHeight;

Legen Sie diese mit Ihrem Körper onload auf dem iframe Inhalt.

Ich habe eine einfache Lösung und erfordert, dass Sie die Breite und Höhe in den Link, um zu bestimmen, versuchen Sie es (es funktioniert mit den meisten Browsern):

<a href='#' onClick=" document.getElementById('myform').src='t2.htm';document.getElementById('myform').width='500px'; document.getElementById('myform').height='400px'; return false">500x400</a>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top