iframe Anpassung funktioniert nicht im IE
deepbluesheep
- javascript
Hallo Leute,
Engin hat mir einen Script empfholen für mein Problem mit der Gästebuch einbindung.
--> http://www.dorfjugend-oberwerrn.de/gaestebuch.php
Mein Problem ist, dass die Seite im Firefox funktioniert, aber im leider im IE nicht.
Kann mir vielleicht einer sagen, wie ich das hin bekomme?
Bitte sagt jetzt nicht, dass ich alles mit CSS machen soll. Das kann ich leider noch nicht.
Vielen Dank für eure Hilfe.
MFG
Felix ;)
Mein Problem ist, dass die Seite im Firefox funktioniert, aber im leider im IE nicht.
Bitte sagt jetzt nicht, dass ich alles mit CSS machen soll. Das kann ich leider noch nicht.
Aber schreiben, was nicht funktioniert, das solltest du schon können. Isse sich hier die Fehlerbehebungsforum nämlich, niche die Fehlersuchforum.
Sorry,
hab ich vergessen...
Also hier nochmal der ganze Fehler.
Im IE wird nur ein bestimmter Bereich dargestellt. Als nur die größe vom div.
Im firefox passt sich der iframe der größe des inhalts vom div an.
Tag in meiner Gästebuchseite (also die Seite in der der iframe ist)...
<div align="center" id="box"><iframe onload="pruefe()"style="height:100px;width:515px;float:"left" align="middle" scrolling="auto" src="http://www.dorfjugend-oberwerrn.de/guestbook/gaestebuch.php" id="detail" name="detail" frameborder="no"> </iframe><br />
</p>
</div>
und hier der javascript:
<script type="text/javascript" language="JavaScript">
<!--
function pruefe() {
if(document.all&&!window.opera) {
var a=document.all.detail;
detail.document.body.scroll='no';
} else {
var a=document.getElementsByName('detail')[0];
a.scrolling='no';
}
var a=document.getElementsByName('detail')[0];
detail.document.getElementsByTagName('body')[0].style.overflow='hidden';
var b=detail.document.getElementById('cont');
if(a.style.height != eval(b.offsetHeight+35)+'px') {
a.style.height=eval(b.offsetHeight+35)+'px';
}
}
//-->
</script>
Viele Grüsse,
Felix
Ich stochere jetzt mal im Nebel rum:
function pruefe() {
if(document.all&&!window.opera) {
var a=document.all.detail;
detail.document.body.scroll='no';
Ist detail im IE hier schon definiert? Ich glaube nicht, sonst könnten wir doch auf die Zeile mit dem a davor verzichten, da steht detail nämlich auch drin.
Außerdem wird hier <body> bearbeitet und in der analogen Zeile im nächsten Block stattdessen …
} else {
var a=document.getElementsByName('detail')[0];
document.getElementById('detail')
a.scrolling='no';
… <iframe>. Ist mir nicht klar.
}
var a=document.getElementsByName('detail')[0];
Überflüssige Zeile, a ist schon gesetzt.
detail.document.getElementsByTagName('body')[0].style.overflow='hidden';
Oben wird noch so ein Aufwand betrieben, um das IE-eigene document.all zu benutzen statt einer getElement-Funktion, und hier soll's plötzlich kein Problem mehr sein?
var b=detail.document.getElementById('cont');
Im Zieldokument stecken fehlerhafterweise zwei Elemente mit der ID cont. Aber davon abgesehen täte ich gleich auf <body> zurückgreifen, da ist wenigstens sicher, dass das immer vorhanden bleibt.
if(a.style.height != eval(b.offsetHeight+35)+'px') {
Auch überflüssig, sage ich jetzt mal, denn dass das beides gleich ist, dürfte seltenst passieren, entsprechend selten wäre Rechenaufwand einzusparen.
a.style.height=eval(b.offsetHeight+35)+'px';
Und wozu das eval(), wo eval() doch evil ist?
}
}
Alles in allem, ganz grob und ohne einen Schimmer, ob das funktioniert:
function pruefe() {
var iframename = 'detail';
if (document.getElementById) {
var a = document.getElementById(iframename);
var b = a.document.getElementsByTagName('body')[0];
a.scrolling = 'no';
}
else if (document.all && !window.opera) {
var a = document.all[iframename];
var b = a.document.tags['body'][0];
b.scroll = 'no';
}
else {
return;
}
b.style.overflow = 'hidden';
a.style.height = (b.offsetHeight + 35) + 'px';
}
"Dieser Fehler wird in den nächsten Tagen behoben."
Da schreibst du doch sicher noch "wird vom SELFHTML-Forum behoben".
Ich stochere jetzt mal im Nebel rum:
Danke für die Mühe!
Um mal auf deine Analyse zurück zukommen...
Ich kann leider gar nichts dazu sagen. Ich weiss von Javascript leider gar nichts. :(
Alles in allem, ganz grob und ohne einen Schimmer, ob das funktioniert:
function pruefe() {
var iframename = 'detail';if (document.getElementById) {
var a = document.getElementById(iframename);
var b = a.document.getElementsByTagName('body')[0];
a.scrolling = 'no';
}
else if (document.all && !window.opera) {
var a = document.all[iframename];
var b = a.document.tags['body'][0];
b.scroll = 'no';
}
else {
return;
}b.style.overflow = 'hidden';
a.style.height = (b.offsetHeight + 35) + 'px';
}
Den script hab ich mal hochgeladen. Das Resultat ist irgendwie echt komisch.
Obwohl scrolling = no ist, kann man trotzdem scrollen und im Firefox ist die Darstellung quasi jetzt wie vorher im IE. Und im IE is sie fast richtig, bis auf die grösse des frames und das man scrollen kann.
>
> > "Dieser Fehler wird in den nächsten Tagen behoben."
>
> Da schreibst du doch sicher noch "wird vom SELFHTML-Forum behoben".
:D Vielleicht kann ich die Jungs ja von einem Link überzeugen (also auf /links.html)
Hab ja bis jetzt hier sehr viel Hilfe bekommen.
Nochmal vielen Dank für deine Hilfe...
Würd mich freuen, wenn dir noch was einfällt!
>
Alles in allem, ganz grob und ohne einen Schimmer, ob das funktioniert:
[…]
Obwohl scrolling = no ist, kann man trotzdem scrollen und im Firefox ist die Darstellung quasi jetzt wie vorher im IE. Und im IE is sie fast richtig, bis auf die grösse des frames und das man scrollen kann.
Gnorz :/ Nachfolgender Code funktioniert jetzt definitiv lokal bei mir in Firefox und IE 6 und sollte auch im IE 5.5 keinen Ärger machen. Und wer noch mit einem IE vor 5.5 unterwegs ist, hat ganz andere Probleme …
function pruefe() {
var iframename = 'detail';
if (! (document.getElementById && document.getElementsByTagName)) {
return;
}
var a = document.getElementById(iframename);
var b = a.contentWindow.document.getElementsByTagName('body')[0];
a.scrolling = 'no';
a.style.height = b.scrollHeight + 'px';
}
Gnorz :/ Nachfolgender Code funktioniert jetzt definitiv lokal bei mir in Firefox und IE 6 und sollte auch im IE 5.5 keinen Ärger machen. Und wer noch mit einem IE vor 5.5 unterwegs ist, hat ganz andere Probleme …
Hey Gonzo,
Vielen vielen Dank für den Script ;)
Der funktioniert wirklich wieder im Firefox, nur leider in meinem IE 7 nicht richtig.
Die Höhe passt er fast perfekt an, aber die Breite stimmt gar nicht. Ausserdem kann man noch scrollen. :(
Ich wollte jetzt probieren die grösse vom Ursprungsframe zu vergrösssern. (das Ergebnis kann ich jetzt nicht anschauen, bin in der FH und kann hier nichts uploaden)
Dein Script ist aber gerade online, wenn du ihn dir anschauen möchtest.
function pruefe() {
var iframename = 'detail';if (! (document.getElementById && document.getElementsByTagName)) {
return;
}var a = document.getElementById(iframename);
var b = a.contentWindow.document.getElementsByTagName('body')[0];a.scrolling = 'no';
a.style.height = b.scrollHeight + 'px';
}
>
Viele Grüsse aus Bayern...
Felix ;)
Ich habe Dir mal etwas in FF2, IE6, IE7, Opera, Safari funktionierendes hochgeladen.
http://www.rkhb.de/pipapo/iframeboss.html
Die beiden Hauptscherz dabei sind, das Iframe zu klonen und mit offsetHeight zu arbeiten:
function resizeIframe (ifr_id)
{
var ifr_old = document.getElementById(ifr_id);
var ifr = ifr_old.cloneNode(true)
ifr.scrolling='no';
ifr.height=ifr_old.contentWindow.document.body.offsetHeight;
ifr_old.parentNode.replaceChild(ifr,ifr_old);
}
Wichtig ist auch, den onload-Event erst in den Body-Tag einzubauen:
<body onload="resizeIframe('ifr1')">
Klaue die Quelltexte und spiele damit herum. Viel Spaß.
viele grüße
ralph
Hallo,
Die beiden Hauptscherz dabei sind, das Iframe zu klonen und mit offsetHeight zu arbeiten:
Warum ist das Klonen nötig?
Und warum nicht scrollHeight?
Mathias
Hallo Mathias,
Warum ist das Klonen nötig?
Und warum nicht scrollHeight?
Mein Hauptaugenmerk lag auf FF2, IE6, IE7, Safari 3.0.4 und Opera 9.24.
Bezüglich Klonen mal eine Resize-Funktion ohne Klonen:
function resizeIframe (ifr_id) // Kein Klonen
{
var ifr = document.getElementById(ifr_id);
ifr.scrolling='no';
ifr.height=ifr.contentWindow.document.body.offsetHeight;
}
Das ursprüngliche Element scrollt bei Bedarf für Benutzer, die Javascript ausgeschaltet haben. Bei der Javascript-Größenänderung bleibt der Scrollbalken bei IE6, IE7, Safari und Opera. Bei Erhöhung von height um 35 verschwindet der Scrollbalken zwar bei IE6/7 und Safari, bleibt aber immer noch bei Opera. Auch ein ifr.style.height hilft da nicht. Bei Opera verschwindet der Scroll-Balken erst, wenn man ifr.scroll='no' angibt. Das ist aber nicht DOM-gerecht und bei den anderen erscheint der Scrollbalken dann wieder, wenn man die 35 weglässt. Im übrigen ist mir unklar, wie der Wert 35 berechnet wird. Darüberhinaus hinaus könnte man statt Klonen auch einen völlig neuen Iframe aufbauen (document.createElement) und diesen z. B. eine andere Seite laden lassen.
Zu offsetHeight: Mein Beispiel gibt ja die verschiedenen Höhenwerte aus. Es ergibt sich folgendes: Safari und Opera erkennen scrollHeight nicht richtig. Opera spinnt immer noch bei clientHeight. Lediglich offsetHeight wird von allen halbwegs richtig erkannt (man muss noch mindestens ein <br> an das Ende setzen).
viele grüße
ralph
Hallo,
das scheint mir noch ziemlich »gewurschtelt«, deshalb hatte ich nochmal nachgefragt. Was mir nicht gefällt:
Erstmal muss man natürlich beachten, dass body nicht den Viewport ausfüllt und zudem in vielen Browser standardmäßig margin hat. Damit ist ein bloßes body.offsetHeight logischerweise ungenau. Also eher documentElement oder das margin/padding bewusst setzen.
Die simple Lösung - Strict Mode, offsetHeight, body { margin:0; } für die Dokumente im iframe, kein Klonen, style.height, kein Setzen von scroll oder scrolling - funktioniert bei mir im IE 6, Firefox 2, Konqueror 3.5.8 und Opera 9.26.
Was du beschreibst, konnte ich so nicht beobachten. Kann aber durchaus sein, dass manche Browser noch Probleme machen. Dann würde ich eher Workarounds suchen, die keine Vorannahmen wie Rendermodus oder bestimmte Konfiguration der Dokumente im iframe machen.
Mathias
das scheint mir noch ziemlich »gewurschtelt«, deshalb hatte ich nochmal nachgefragt.
Ach so. Und ich dachte, Dich hätten die Beweggründe für meine Vorgehensweise *ernsthaft* interessiert.
viele grüße
ralph
Hallo,
das scheint mir noch ziemlich »gewurschtelt«, deshalb hatte ich nochmal nachgefragt.
Ach so. Und ich dachte, Dich hätten die Beweggründe für meine Vorgehensweise *ernsthaft* interessiert.
Ja, haben sie auch. Ich habe sie überprüft und bin z.T. zu anderen Ergebnissen gekommen, die meine Vorannahme, dass es möglicherweise auch einfacher geht, bestätigt haben.
Mathias
Also ich wollte mich nochmal für eure Hilfe bedanken! ;)
Jetzt funktioniert der script wie ich es mir gewünscht habe.
Bei eurer Disskusion ob das jetzt gewurschtelt ist oder nicht, kann ich leider nicht mit reden.
Vielleicht in ein paar Jahren! ;)
Viele Grüsse aus Bayern,
Felix ;)
Der funktioniert wirklich wieder im Firefox, nur leider in meinem IE 7 nicht richtig.
Die Höhe passt er fast perfekt an, aber die Breite stimmt gar nicht.
An der Breite wird ja auch nichts gemacht, die bleibt so, wie sie ursprünglich angegeben wurde. Für eine Automatik kannst du es mal mit der zusätzlichen Zeile
a.style.width = b.scrollWidth + 'px';
probieren, ich täte aber lieber die Breite des <iframe>-Elements direkt angeben.
Ausserdem kann man noch scrollen. :(
Setze im <iframe>-Element das Attribut scrolling auf no statt auf auto. Die Zeile mit dem a.scrolling = 'no'; kannst du dann auch rausnehmen.
Ich war gerade an dem Rechner von meinem Mitbewohner und beim funktioniert alles einwandfrei!
Kann mir einer sagen, warum das in meinem IE7 nicht richtig dargestellt wird?
Hallo,
if (document.getElementById) {
var a = document.getElementById(iframename);
var b = a.document.getElementsByTagName('body')[0];
Im Firefox haben iframe-Elementknoten keine Eigenschaft »document«, siehe </archiv/2006/8/t134560/#m873073>.
Besser:
var body = iframe.contentDocument || iframe.document;
Und dann einfach .body anstatt dieser Wurschtelei. Das body-Element ist immer unter document.body verfügbar.
a.scrolling = 'no';
}
else if (document.all && !window.opera) {
Opera kann getElementById genauso lange wie document.all, also kann man das hier weglassen, weil er in den ersten Teil einsteigen wird.
var a = document.all[iframename];
var b = a.document.tags['body'][0];
document.body, siehe oben.
Andererseits kann man IE-4-Unterstützung auch einfach weglassen...
function pruefe() {
var iframename = 'detail';
if (!document.getElementById) return;
var iframe = document.getElementById(iframename);
var body = iframe.contentDocument || iframe.document;
iframe.scrolling = 'no';
iframe.style.height = (body.offsetHeight + 35) + 'px'; // vielleicht eher scrollHeight
body.scroll = 'no'; // ist auch unnötig, glaube ich, wenn man eh overflow:hidden setzt
body.style.overflow = 'hidden';
}
Mathias
Hallo molily!
So funzt(TM) das Skript aber auch nicht...
function pruefe() {
var iframename = 'detail';
if (!document.getElementById) return;var iframe = document.getElementById(iframename);
var body = iframe.contentDocument || iframe.document;iframe.scrolling = 'no';
iframe.style.height = (body.offsetHeight + 35) + 'px'; // vielleicht eher scrollHeight
body.scroll = 'no'; // ist auch unnötig, glaube ich, wenn man eh overflow:hidden setzt
body.style.overflow = 'hidden';
}
»body.style has no properties«, sagt der Feuerfuchs. Weil die Variable »body« ja nur das »document« ist, und nicht der document.body. Darum geht es so:
`var body = iframe.contentDocument.body || iframe.document.body;`{:.language-javascript}
...aber nicht im IE 6 -> »'contentDocument.Body' ist Null oder kein Objekt« . Invertiert man die ODER-Verknüpfung geht es im IE, dafür nicht im FF -> »iframe.document has no properties«.
Eine Browser-Abfrage müsste also doch her, oder?
Viele Grüße aus Frankfurt/Main,
Patrick
--
![](http://www.atomic-eggs.com/fuernA.jpg)
\_ - jenseits vom delirium - \_
[[link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash](http://www.atomic-eggs.com/)]
Nichts ist unmöglich? [Doch!](http://www.atomic-eggs.com/cwi/cwi_4.shtml)
Heute schon ge[gök](http://goek.atomic-eggs.com/goek_goek.html)t?
Re!
rkhb liefert hier das Stichwort:
contentWindow.document.body
So geht's:
<script type="text/javascript">
function pruefe() {
var iframename = 'detail';
if (!document.getElementById) return;
var iframe = document.getElementById(iframename);
var body = iframe.contentWindow.document.body;
iframe.scrolling = 'no';
iframe.style.height = (body.offsetHeight + 35) + 'px';
body.style.overflow = 'hidden';
}
window.onload = pruefe;
</script>
Lebendes Beispiel...
Viele Grüße aus Frankfurt/Main,
Patrick
Hallo,
Danke für den Hinweis, der Code war halt ungetestet und sollte bloß das Schema vorstellen.
Auf die verschiedenen Möglichkeiten, auf ein Fenster- bzw. Dokumentobjekt eines iframes zugreifen kann, habe ich im verlinkten Posting hingewiesen, ebenso der Grund, warum ich contentDocument präferiere.
Mathias
Hi,
var body = iframe.contentDocument.body || iframe.document.body;
...aber nicht im IE 6 -> »'contentDocument.Body' ist Null oder kein Objekt« . Invertiert man die ODER-Verknüpfung geht es im IE, dafür nicht im FF -> »iframe.document has no properties«.
Eine Browser-Abfrage müsste also doch her, oder?
Noe, man muesste nur erst mal die Existenz der "oberen" Objekte testen, bevor man auf darunter liegende Objekte oder Eigenschaften zugreifen will.
Wenn x.y nicht existiert, muss der Zugriff auf x.y.z einen Fehler geben.
if(x.y && x.y.z) hingegen ginge, da von links nach rechts abgearbeitet wird, und bei UND-Verknuepfung abgebrochen wird, sobald wir ein erstes false antreffen.
MfG ChrisB
Hallo ChrisB!
Noe, man muesste nur erst mal die Existenz der "oberen" Objekte testen, bevor man auf darunter liegende Objekte oder Eigenschaften zugreifen will.
Wenn x.y nicht existiert, muss der Zugriff auf x.y.z einen Fehler geben.
if(x.y && x.y.z) hingegen ginge, da von links nach rechts abgearbeitet wird, und bei UND-Verknuepfung abgebrochen wird, sobald wir ein erstes false antreffen.
Tut mir leid, wenn ich vor lauter Perlen nicht mehr so fit in JS bin. Wenn ich in Perl in einer sub schreibe:
my $somewhat = shift || myOtherSub();
wird entweder der Wert von der Übergabe (shift vom @_) oder eben das, was »myOtherSub« als Rückgabewert bereit hält.
Ich dachte, dass:
var xy = foo || bar;
in JS genauso gehandhabt wird, dass wenn "foo" nicht existiert eben "bar" genommen wird, was anscheinend nicht der Fall ist. Denn wenn "foo" schon falsch ist, wird in JS gar nicht nach der Alternative "bar" geprüft sondern mit einer Fehlermeldung abgebrochen...?
Viele Grüße aus Frankfurt/Main,
Patrick
Hi,
Tut mir leid, wenn ich vor lauter Perlen nicht mehr so fit in JS bin. Wenn ich in Perl in einer sub schreibe:
my $somewhat = shift || myOtherSub();
wird entweder der Wert von der Übergabe (shift vom @_) oder eben das, was »myOtherSub« als Rückgabewert bereit hält.
Ich dachte, dass:
var xy = foo || bar;
in JS genauso gehandhabt wird, dass wenn "foo" nicht existiert eben "bar" genommen wird,
Ja, dem ist durchaus so.
(Genauer natuerlich: Wenn der Ausdruck, den foo darstellt, zu false evaluiert wird.)
was anscheinend nicht der Fall ist. Denn wenn "foo" schon falsch ist, wird in JS gar nicht nach der Alternative "bar" geprüft sondern mit einer Fehlermeldung abgebrochen...?
Nein,
var xy = foo.abc || bar.def;
ist hier der problematische Fall.
Wenn es gar kein foo gibt, *dann* gibt der Versuch auf dessen Eigenschaft abc zuzugreifen, einen Fehler und damit Abbruch.
Wenn ich dich frage, ob dein Hund ("Objekt") auf meinen Rasen gekackt hat ("Eigenschaft") - dann reagierst du vermutlich ziemlich angepisst ("Fehlermeldung"), wenn eben dieser letzte Woche vom Auto ueberfahren wurde.
Deshalb frage ich dich natuerlich erst mal, wie's deinem niedlichen kleinen Pinscher den so geht - und kann mir dann gegebenenfalls die Frage, ob er auf meinen Rasen geschissen hat, verkneifen ...
MfG ChrisB
Grundlage für Zitat #986.
Hallo,
var xy = foo || bar;
in JS genauso gehandhabt wird, dass wenn "foo" nicht existiert eben "bar" genommen wird
Nein, das kann man nie dazu benutzen, um abzufragen, ob eine Variable nicht *existiert*.
Verallgemeinert: Man kann nie Boolean(variable) verwenden, um abzufragen, ob eine Variable existiert. Denn das wird intern bei if (...) angewendet oder halt bei Operatoren wie && oder ||.
foo || bar verwendet man z.B. bei Variablen, die nicht gesetzt wurden. Das mit var foo, bar; oder mit function func (foo, bar) deklarierte, ohne dass ihnen ein Wert zugewiesen wurde. Beide haben dann den Wert Typ Undefined. Das ist etwas anderes als »nicht existent sein«.
Warum das einen Unterschied macht: Wenn man die Identifier Reference foo notiert und es existiert unter dem Namen foo nichts, dann gibts beim Auflösen dieses Namens einen ReferenceError. Wenn foo existiert, aber vom Typ Undefined ist, dann ergibt das Auflösen einfach den Wert undefined und kein Error wird ausgelöst.
Mathias
Hallo Mathias und Christoph!
Danke für die Erläuterungen - und den Vergleich mit dem Hund! ;)
Viele Grüße aus Frankfurt/Main,
Patrick