Kalle_B: iframe-Höhe an Inhalt anpassen - Lösung gefunden

Hallöle,

endlich klappt es - ein iframe passt sich der Höhe des Inhalts an, auch wenn das Dokument im iframe von einer fremden Domain kommt. Allerdings nur in dem Sonderfall, dass der Inhalt mitspielt und seine Höhe meldet:
Veranstaltungskalender

Das rufende Dokument (das mit dem iframe) ist http://osmer.de/termine.php, im Folgenden *osmer* genannt (PHP wird hier nur zum Einbinden des Menüs gebraucht, hat nichts mit unserem Thema zu tun).

Das gerufene Dokument (im iframe) ist zunächst http://remso.de?ORT=9669&OT=1&lg=de2, im Folgenden *remso* genannt.

In *osmer* können Links angeklickt werden, um andere Inhalte von *remso* in das iframe zu laden. Jedesmal wird die iframe- Höhe angepasst.

Konzept:
--------
*remso* bestimmt seine Höhe und meldet die per Ajax an seinen eigenen Server. Der erstellt ein GIF- Bild mit dieser Höhe und legt es als Datei ab. Nach einer gewissen Verzögerungszeit liest *osmer* dieses Bild von *remso* und macht das iframe so hoch wie das Bild.

Einzelschritte:
---------------
1. *osmer* bestimmt einen zufälligen Namen für das Bild, damit mehrere Benutzer unabhängig arbeiten können:
var gif_name = 'img' +Math.random();
und übergibt den als Parameter an den iframe- Source.

2. *remso* lädt sich in den iframe und bestimmt unmittelbar vor dem </body> seine eigene Höhe:

<div id=ganzunten></div>  
<script type="text/javascript">  
  var gif_hoehe  = document.getElementById('ganzunten').offsetTop;  

3. *remso* ruft per Ajax ein Programm auf seinem eigenen Server, das unter Verwendung des Bildnamens ein Bild mit der gewünschten Höhe erzeugt:

  var programm = "http://remso.de/gif_create.php?gif_name=[gif_name]&breite=" +gif_breite +"&hoehe=" +gif_hoehe;  

... und auf dem remso- Server als Datei speichert:

  $resource = imagecreate( $arr_in['breite'], $arr_in['hoehe'] ); // x, y  
  imagegif ( $resource, $arr_in['gif_name'].'.gif' );  

4. *oamer* liest nach einem Timeout von 3 sec. (wg. *remso* laden und Bild erzeugen) dieses Bild und gibt dessen Höhe an den iframe weiter:

<script type="text/javascript">  
var gif_name = 'img' +Math.random();  
var gif_nr   = 0;  
function frameHoehe()  
{  
  var p591_img = new Image();  
  gif_nr++;  
  p591_img.src = "http://remso.de/" +gif_name +".gif?nr=" +gif_nr;  
  ...  
  document.getElementById( 'remsoframe' ).style.height = p591_img.height;  

Und das Prozedere kann nacheinander für mehrere *remso* durchgespielt werden.

Lieben Gruß und danke für die Unterstützung,
Kalle

  1. Hallo,

    wegen der Seite hat sich mein FireFox aufgehangen!
    "Was hat er getan!?" ...

    MfG. Christoph Ludwig

    --
    Wo die Sprache aufhört, fängt die Musik an...
    Selfcode:  ie:( fl:| br:^ va:| ls:/ fo:| rl:? n4:) ss:) de:] js:) ch:{ sh:) mo:) zu:)
    Go to this
    1. Hallo,

      wegen der Seite hat sich mein FireFox aufgehangen!

      Uups - getestet habe ich bisher nur mit Opera. Ist ein Prototyp, muss wohl noch verfeinert werden.

      Kalle

      1. Uups - getestet habe ich bisher nur mit Opera. Ist ein Prototyp, muss wohl noch verfeinert werden.

        Habe diese Schleife im Verdacht:

          var p591_img = new Image();  
          gif_nr++;  
          p591_img.src = "http://remso.de/" +gif_name +".gif?nr=" +gif_nr;  
          
          while ( !p591_img.complete )  
          {  
            for( i=0; i<100; i++ );  
          }  
          if ( !p591_img.height )  
          {  
            alert( "Datei " +"http://remso.de/" +gif_name +".gif nicht gefunden" ); // pause  
          }  
          document.getElementById( 'remsoframe' ).style.height = p591_img.height;  
        
        

        Kann es sein, dass FF complete nicht versteht? Ich muss das Bild komplett haben, sonst kann ich die Höhe nicht auslesen

        Kalle

        1. Hi,

          Habe diese Schleife im Verdacht:

          while ( !p591_img.complete )

          Kann es sein, dass FF complete nicht versteht? Ich muss das Bild komplett haben, sonst kann ich die Höhe nicht auslesen

          Dann solltest du den load-Event des Bildes zum Triggern der weiteren Funktionalitaet nutzen.

          MfG ChrisB

          --
          „This is the author's opinion, not necessarily that of Starbucks.“
          1. Dann solltest du den load-Event des Bildes zum Triggern der weiteren Funktionalitaet nutzen.

            Wie geht das? Gilt das dann (hoffentlich) für alle Browser?

            Kalle

            1. Wie geht das? Gilt das dann (hoffentlich) für alle Browser?

              SElfHtml meint, onload gilt für <http://de.selfhtml.org/javascript/sprache/eventhandler.htm#onload@title=<frameset> und <body>>

              Während hier behauptet wird "The onload event occurs immediately after a page or an image is loaded."

              Aber es wird nicht verraten, wie.

              Dies hier klappt nicht:

                while ( !p591_img.complete )  
                {  
                  for( i=0; i<100; i++ );  
                  if ( p591_img.onload ) alert ( "Bild ist da" );  
                }  
              
              

              Kalle

              1. SElfHtml meint, onload gilt für <http://de.selfhtml.org/javascript/sprache/eventhandler.htm#onload@title=<frameset> und <body>>

                Stimmt nicht, gilt z.B. auch für iframe und img/Image-Objekte.

                while ( !p591_img.complete )
                  {
                    for( i=0; i<100; i++ );
                    if ( p591_img.onload ) alert ( "Bild ist da" );

                Da hast du etwas grundsätzlich missverstanden: JavaScript funktioniert strikt asynchron. Es gibt kein »Warten«, wie man es aus anderen Programmiersprachen kennt - wenn du so etwas machst, würde der Browser einfrieren. So etwas wie for( i=0; i<100; i++ ); oder while (img.complete) {} ist in JavaScript Unsinn. Das kann man im Prinzip machen, führt aber nicht zum Erfolg und es gibt i.d.R. bessere Methoden.

                JavaScript arbeitet mit Ereignissen und, wenn es um regelmäßige Abfragen geht, mit Timeouts und Intervallen. Ereignisverarbeitung ist etwas anderes als Abfrage von Eigenschaften. Man definiert eine Handler-Funktion, die beim Eintreten des Events ausgeführt wird.

                http://de.selfhtml.org/javascript/objekte/event.htm#allgemeines
                http://redaktion.selfhtml.org/selfhtml-preview/javascript/konzepte.html#events
                http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#traditionelles-event-handling

                if (img.complete) { // Falls das Bild schon im Browsercache liegt
                   loaded();
                } else { // ansonsten warte auf den load-Event
                   img.onload = loadHandler;
                }

                Dazu die Handlerfunktion:

                function loadHandler () {
                  alert("Bild ist da!");
                }

                Mathias

  2. Hallo Kalle_B!

    Veranstaltungskalender

    Nur zur Info: http://www.atomic-eggs.com/z_testdir/shots/kalle.gif (ließ sich bei jedem Aufruf reproduzieren).

    Viele Grüße aus Frankfurt/Main,
    Patrick

    --
    _ - jenseits vom delirium - _

       Diblom   [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
    J'ai 10 ans! | Achtung Agentur! | Nichts ist unmöglich? Doch! | Heute schon gegökt?
  3. ... blende ich den zufällig erzeugten Bildnamen oben links im iframe ein.´, z.B.
    img0.14324279804714024

    Das zugehörige Bild mit der iframe- Höhe ist dann http://remso.de/img0.14324279804714024.gif

    (um nachzusehen, ob es da ist)

    Kalle

  4. So, nun klappt es auch im IE und FF.

    Bein Anfordern des Bildes nutze ich den onload:

      p591_img        = new Image();  
      p591_img.src    = "http://remso.de/" +gif_name +".gif";  
      p591_img.onload = imageLoaded();  
    
    

    Allerdings, kann in imageLoaded() die Höhe p591_img.height nicht _sofort_ aufgerufen werden. Wenn zuerst ein Alert als Pause eingesetzt wird, klappt es aber. Alert ist ungeschickt, deshalb so:

    function setzeHoehe()  
    {  
      if (!p591_img.height ) alert ( "Bild " +gif_name +".gif ist " +p591_img.height +"px hoch" );  
      if ( p591_img.height ) document.getElementById( 'remsoframe' ).style.height = p591_img.height +'px';  
    }  
    function imageLoaded()  
    {  
      // Image geladen? Jedenfalls kann die Hoehe noch nicht abgefragt werden  
      window.setTimeout( 'setzeHoehe()', 1000 );  
    }  
    
    

    Hat jemand eine Erklärung dafür, warum 1 sec. gewartet werden muss, bis beim geladenen Bild die Höhe abgefragt werden kann?

    Feuert der onload zu früh?

    LG Kalle

    1. Bein Anfordern des Bildes nutze ich den onload:

      Nein, tut du nicht.

      p591_img        = new Image();

      p591_img.src    = "http://remso.de/" +gif_name +".gif";
        p591_img.onload = imageLoaded();

        
      Du weist dem onload Eventhandler den Rückgabewert der Funktion imageLoaded() zu. Eventhandler erwarten eine Funktionsreferenz. In deinem Fall reicht:  
      `   p591_img.onload = imageLoaded;`{:.language-javascript}  
        
        
      Struppi.
      
      1. Hallo, Struppi,

        »» ~~~javascript

        p591_img        = new Image();

        »»   p591_img.onload = imageLoaded();
        »»

        
        >   
        > Du weist dem onload Eventhandler den Rückgabewert der Funktion imageLoaded() zu.  
          
        Danke für den Hinweis.  
          
        Kalle
        
      1. »»   p591_img.onload = imageLoaded();

        http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#traditionelles-event-handling
        http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#fehler-handler-aufrufen

        Habe mich halt aufs Glatteis (ver)führen lassen wegen
        <body onload="dingsBums()">

        Da braucht es die Klammern unbedingt. Ich weiss, andere Baustelle ...

        Kalle

        1. Habe mich halt aufs Glatteis (ver)führen lassen wegen
          <body onload="dingsBums()">

          Da braucht es die Klammern unbedingt. Ich weiss, andere Baustelle ...

          Das ist nicht grundsätzlich falsch gedacht, weil im Prinzip dieselbe, aber aus historischen Gründen doch eine andere Baustelle:
          http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#fehler-code-als-string

          Mal eine Übersicht:

          HTML Inline-Event-Handler:
          <element onevent="handlerfunktion()">

          Traditionelles Event-Handling gemäß Netscape JavaScript:
          element.onevent = handlerfunktion;

          Attribut über DOM setzen:
          element.setAttribute("onevent", "handlerfunktion()")
          (geht nur prinzipiell - praktisch nicht browserübergreifend)

          Und wo wir gerade dabei sind auch:

          DOM 2 Events:
          element.addEventListener("event", handlerfunktion, false);

          IE
          element.attachEvent("onevent", handlerfunktion);

          (Diese ganzen Methoden haben nur grob denselben Effekt, im Detail aber krasse Unterschiede, u.a. was den Zugriff aufs Event-Objekt und das verarbeitende Element angeht.)

          Mathias