iframe-Höhe an Inhalt anpassen - Lösung gefunden
Kalle_B
- javascript
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
Hallo,
wegen der Seite hat sich mein FireFox aufgehangen!
"Was hat er getan!?" ...
MfG. Christoph Ludwig
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
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
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
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
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
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
Hallo Kalle_B!
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
... 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
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
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.
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
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
(Ich schreibe mal einen Linksetzer-Bot ;-))
Mathias
»» 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
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