Der IE und das "windowed" SELECT-Feld...
Yeti
- html
Hallo liebe Forumsbesucher!
Ich würde den Internet Explorer am liebsten in die Tonne treten, aber was soll man machen in einem Unternehmen, wo man in der IT-Hierarchie ganz unten sitzt...
Ich habe ein schönes Design entworfen, bei dem oben und unten Menüleisten mit style="position: fixed" festgehalten werden. Frames sind ja eklich. Hab ich jetzt sogar dank IE7 (http://dean.edwards.name/IE7) dem Internet Exploiter beigebracht.
Problem: Wenn ich jetzt ein SELECT-Feld auf der Seite habe und diese Seite so lang ist, dass beim Scrollen das Feld nach oben hin aus der Seite verschwinden sollte, kommt folgendes heraus (das Feld sollte hinter der Navigation verschwinden, wie es der Rest der Seite tut):
<img src="http://archer.jtis.de/ie-fehler.jpg" border="0" alt="">
Bruaaah!
z-index hat keine Wirkung.
Nach längerem Googlen, bin ich auf die Aussage gestoßen, dass SELECT-Felder im IE sogenannte "windowed" Elemente sind, die nicht per CSS gestylet werden können (na toll).
Meine Frage: Hat jemand eine andere Lösung als http://www.devguru.com/features/tutorials/ComboControl/combocontrol.html? Das funktioniert zwar, find ich aber unschön, zumal dafür mehr HTML-Code und vor allem JScript/VBScript nötig ist als für <select><option></select>...
Der Yeti
Hi,
Ich würde den Internet Explorer am liebsten in die Tonne treten, aber was soll man machen in einem Unternehmen, wo man in der IT-Hierarchie ganz unten sitzt...
wie wahr, wie wahr ...
Nach längerem Googlen, bin ich auf die Aussage gestoßen, dass SELECT-Felder im IE sogenannte "windowed" Elemente sind, die nicht per CSS gestylet werden können (na toll).
"Nicht" stimmt natürlich nicht ganz :-) aber man kann nicht verhindern, dass das Element zuoberst angezeigt wird. Dir bleibt nur, die visibility auf hidden zu setzen (oder etwas Vergleichbares). Möglicherweise hilft Dir hierbei der proprietäre expression()-Eigenschaftswert, natürlich in Verbindung mit einem geeigneten CSS-Hack.
Cheatah
Hi,
"Nicht" stimmt natürlich nicht ganz :-) aber man kann nicht verhindern, dass das Element zuoberst angezeigt wird. Dir bleibt nur, die visibility auf hidden zu setzen (oder etwas Vergleichbares). Möglicherweise hilft Dir hierbei der proprietäre expression()-Eigenschaftswert, natürlich in Verbindung mit einem geeigneten CSS-Hack.
Richtig, den Text kann ich schon stylen, aber ich kann ja auch z.B. keinen Rahmen machen.
Das mit der visibility klingt gut, aber wie bekomme ich raus, wann das Element höher als die untere Grenze des Menüs ist?
Expression(): War das nicht dieses häßliche Workaround für "position: fixed;", wo die "fixen" Elemente immer so rumhoppelten? ;-)
Ich werd mich mal schlau machen, erstmal danke für den Tipp!
Der Yeti
Hi,
Das mit der visibility klingt gut, aber wie bekomme ich raus, wann das Element höher als die untere Grenze des Menüs ist?
die Scrollposition mit den bekannten Ausmaßen des Menüs korrelieren.
Expression(): War das nicht dieses häßliche Workaround für "position: fixed;", wo die "fixen" Elemente immer so rumhoppelten? ;-)
expression() ist auf jeden Fall ein hässlicher Workaround ;-) aber es ermöglicht die dynamische Berechnung von CSS-Werten im IE. Du kannst beliebigen JavaScript-Code einfügen, der lediglich einen gültigen CSS-Wert zurückliefern muss.
Cheatah
Hi,
die Scrollposition mit den bekannten Ausmaßen des Menüs korrelieren.
Genau. Und daran scheiter ich im Moment. ;-)
Hast du auch einen praktischen Tipp? Habe schon versucht mit offsetTop, offsetParent oder ähnlichem die Position des SELECTs herauszufinden, sie ist immer 0 da es wohl vom umgebenden CENTER aus gerechnet wird und nicht vom body.
Habe auch schon das SELECT nur von einem DIV umgeben, weil es bei http://www.dhtmlcentral.com/projects/lib/examples.html?m=56 so zumindest geht. Allerdings ist deren Code ziemlich komprimiert und ich will nicht unbedingt die ganze Library einbinden (müssen).
expression() ist auf jeden Fall ein hässlicher Workaround ;-) aber es ermöglicht die dynamische Berechnung von CSS-Werten im IE. Du kannst beliebigen JavaScript-Code einfügen, der lediglich einen gültigen CSS-Wert zurückliefern muss.
Jo, das ist wirklich nett. Außer, wenn man expression(alert(this.offsetTop)) schreibt und sich damit selbst in einer Endlosschleife gefangen hält, weil das Event jede Millisekunde oder so feuert. ;-)
Der Yeti
Hi,
Hast du auch einen praktischen Tipp? Habe schon versucht mit offsetTop, offsetParent oder ähnlichem die Position des SELECTs herauszufinden, sie ist immer 0 da es wohl vom umgebenden CENTER aus gerechnet wird und nicht vom body.
Du benutzt <center>?! Böse! ;-) Unabhängig davon: Auch dieses Element hat ein offsetTop, und das darüber liegende auch, und das darüber liegende auch, und das ...
Btw, bist Du sicher, in der expression() das richtige Element referenziert zu haben?
Jo, das ist wirklich nett. Außer, wenn man expression(alert(this.offsetTop)) schreibt und sich damit selbst in einer Endlosschleife gefangen hält, weil das Event jede Millisekunde oder so feuert. ;-)
Hehe, die Erfahrung muss jeder mal machen ;-)
Cheatah
Hi,
Du benutzt <center>?! Böse! ;-) Unabhängig davon: Auch dieses Element hat ein offsetTop, und das darüber liegende auch, und das darüber liegende auch, und das ...
Ist weniger zu schreiben und nur zum testen ...
Das Problem ist, alle offsetTop's sind 0! (?!?)
Außerdem würde ich das gerne für alle SELECT-Felder auf der gesamten Webseite haben, die ja auf einer beliebigen Ebene im Elementbaum liegen können. Dann muss ich wahrscheinlich eine Schleife schreiben, um alle offsetTop's > 0 zusammenzuzählen...
Btw, bist Du sicher, in der expression() das richtige Element referenziert zu haben?
Nun ja, es heißt:
select { top: expression(window.status=this.offsetTop); }
Das sollte doch eigentlich auf das select-Feld verweisen. ;-)
Tut es auch, this.tagName gibt nämlich SELECT aus.
Aber schon mal vielen Dank für deine Hilfe, auch wenn ich noch nicht ganz am Ziel bin!
Um es mit Bastian Pastewka zu sagen: "Ich war noch niiie so nah an ner Lösung!" (Genial daneben)
Der Yeti
Hi,
Das Problem ist, alle offsetTop's sind 0! (?!?)
ich habe es gerade mal getestet: Bei mir ergibt sich der richtige Wert, egal ob ich das Element schachtele oder nicht.
Außerdem würde ich das gerne für alle SELECT-Felder auf der gesamten Webseite haben, die ja auf einer beliebigen Ebene im Elementbaum liegen können. Dann muss ich wahrscheinlich eine Schleife schreiben, um alle offsetTop's > 0 zusammenzuzählen...
Ich dachte an eine Rekursion ...
Um es mit Bastian Pastewka zu sagen: "Ich war noch niiie so nah an ner Lösung!" (Genial daneben)
*g* Naja, nur hat offsetTop nichts mit der Scrollposition zu tun ;-)
Cheatah
Hi,
*g* Naja, nur hat offsetTop nichts mit der Scrollposition zu tun ;-)
Richtig.
Der Yeti
Hi,
juchu! Endlich hab ich's!
Der Code hat mich zwar einige Gehirnwindungen gekostet, aber es läuft!
Leider wird das Feld nicht halb verschluckt sondern nur komplett, aber das ist Kosmetik.
Danke, Cheatah!
Falls jemand daran auch verzweifelt...
CSS-Datei:
"select { visibility: expression(hideSelect(this)); }"
HTML/JS-Datei:
" function hideSelect(dies)
{
var offset = dies.offsetHeight;
var elem = dies;
while (elem.parentElement && elem.parentElement.tagName != "BODY")
{
elem = elem.parentElement;
offset += elem.offsetTop;
}
var obererRand = offset-83; // 83 = Höhe des oberen DIVs + Höhe des SELECT-Feldes
var untererRand = offset-document.body.offsetHeight+31; // 31 = Höhe des unteren DIVs
if (document.body.scrollTop > obererRand || document.body.scrollTop < untererRand)
return "hidden";
else
return "visible";
}
"
Leider hab ich es noch nicht geschafft, die Größen (83 und 31 Pixel) dynamisch zu erfassen, aber da es bei mir egal ist und ich mal langsam voran kommen muss mit dem Projekt, lass ich es jetzt so.
Der Yeti
Hallo.
[...]
var obererRand = offset-83; // 83 = Höhe des oberen DIVs + Höhe des SELECT-Feldes
var untererRand = offset-document.body.offsetHeight+31; // 31 = Höhe des unteren DIVs
if (document.body.scrollTop > obererRand || document.body.scrollTop < untererRand)
return "hidden";
else
return "visible";
}
"Leider hab ich es noch nicht geschafft, die Größen (83 und 31 Pixel) dynamisch zu erfassen, aber da es bei mir egal ist und ich mal langsam voran kommen muss mit dem Projekt, lass ich es jetzt so.
Übersetze doch einfach deinen Kommentar ins Englische und haue ein paar Punkte dazwischen und fast ist die Dynamik fertig.
MfG, at
Hi @,
Übersetze doch einfach deinen Kommentar ins Englische und haue ein paar Punkte dazwischen und fast ist die Dynamik fertig.
Eben nur fast. Habe ein bisschen rumprobiert, aber das ist jetzt auch egal, viel mehr Zeit zu investieren lohnt nicht.
parseInt(document.getElementById("divoben").style.height) brachte leider "NaN"...
Der Yeti
Hi,
parseInt(document.getElementById("divoben").style.height) brachte leider "NaN"...
das liegt daran, dass Du dem <element id="divoben"> kein style="height: irgendwas" gegeben hast - oder der Wert keine Zahl ist ;-)
Cheatah
Hi,
das liegt daran, dass Du dem <element id="divoben"> kein style="height: irgendwas" gegeben hast - oder der Wert keine Zahl ist ;-)
Schlaumeier... ;-)
Es heißt <div id="divoben" style="height: 31px;" ...> aber das ist mir jetzt egal. Es läuft! Pasta!
Der Yeti
Hi,
"select { visibility: expression(hideSelect(this)); }"
select {
visibility: expression(getYPosition(this, 0) < 83 ? 'hidden' : 'visible');
}
HTML/JS-Datei:
function getYPosition(obj, pos) {
if (obj.parentElement && obj.parentElement.tagName.toUpperCase() != "BODY") {
return getYPosition(obj.parentElement, pos+obj.offsetTop }
return pos-document.body.scrollTop;
}
Natürlich ungetestet. Aber müsste es nicht eigentlich parentNode statt parentElement heißen?
Leider hab ich es noch nicht geschafft, die Größen (83 und 31 Pixel) dynamisch zu erfassen,
Siehe oben ;-)
aber da es bei mir egal ist und ich mal langsam voran kommen muss mit dem Projekt, lass ich es jetzt so.
Es ist gut, eine Lösung zu haben. Sie zu hinterfragen und nach einer besseren zu suchen, ist besser.
Cheatah
Hi,
select {
visibility: expression(getYPosition(this, 0) < 83 ? 'hidden' : 'visible');
}
Die 83 kannst du aber auch dynamisch ermitteln! *scnr*
HTML/JS-Datei:
function getYPosition(obj, pos) {
if (obj.parentElement && obj.parentElement.tagName.toUpperCase() != "BODY") {
return getYPosition(obj.parentElement, pos+obj.offsetTop }
return pos-document.body.scrollTop;
}Natürlich ungetestet. Aber müsste es nicht eigentlich parentNode statt parentElement heißen?
Natürlich. Bei mir ist es aber getestet und KLAPPT! :-)
Da ich mich nur an den IE halten muss, habe ich es bei parentElement belassen. (http://de.selfhtml.org/javascript/objekte/all.htm#parent_element)
Es ist gut, eine Lösung zu haben. Sie zu hinterfragen und nach einer besseren zu suchen, ist besser.
Ja, aber für schönen Code werde ich nicht bezahlt. :-p
Der Yeti
Hi,
visibility: expression(getYPosition(this, 0) < 83 ? 'hidden' : 'visible');
Die 83 kannst du aber auch dynamisch ermitteln! *scnr*
sicher doch. Da sie sich aber aus dem anderen CSS-Code ergibt, welchen Du auf die selbe Weise in der Hand hast wie obige Zeile, ist das IMHO so schon in Ordnung.
Natürlich ungetestet. Aber müsste es nicht eigentlich parentNode statt parentElement heißen?
Natürlich. Bei mir ist es aber getestet und KLAPPT! :-)
Freut mich zu hören :-)
Da ich mich nur an den IE halten muss, habe ich es bei parentElement belassen.
Logisch, aber gibt's irgendwelche Nachteile, wenn Du die standardkonforme Schreibweise verwendest? Wenn nicht, würde ich diese potenzielle Fehlerquelle gleich mit ausschließen.
Es ist gut, eine Lösung zu haben. Sie zu hinterfragen und nach einer besseren zu suchen, ist besser.
Ja, aber für schönen Code werde ich nicht bezahlt. :-p
Eher im Gegenteil: Wenn Du schlechten (=unwartbaren) Code schreibst, musst Du für jede Veränderung einbezogen werden, machst Dich also unverzichtbar ;-)
Cheatah
Hi,
Eher im Gegenteil: Wenn Du schlechten (=unwartbaren) Code schreibst, musst Du für jede Veränderung einbezogen werden, machst Dich also unverzichtbar ;-)
Schon. Aber eine verkürzte IF-Abfrage à la ($watis)?tuwat():tunix() ist sicherlich nicht so übersichtlich wie
if ($watis)
tuwat();
else
tunix();
Habe ich zwar auch oft verwendet, aber ich finde meine Version tatsächlich übersichtlicher und zumal ich sie auch selber geschrieben habe, steige wenigstens _ich_ durch. ;-)
Außerdem _will_ ich mich ja unentbehrlich machen! Schließlich muss irgendwann mehr Geld her und da braucht man jede Verhandlungsmacht, die man kriegen kann ("mehr Geld oder ihr könnt eure Abrechnung wieder mit Papier und Bleistift machen!")...
Der Yeti
Du benutzt <center>?! Böse! ;-) Unabhängig davon: Auch dieses Element hat ein offsetTop, und das darüber liegende auch, und das darüber liegende auch, und das ...
Aaah, hab jetzt ein bisschen aufgeräumt und siehe da, direkt unter einem P ergibt this.parentElement.offsetTop einen Wert von 169. Juchu! Allerdings: Der bleibt immer gleich, egal wie ich scrolle. Ist also wahrscheinlich der Abstand zum oberen Ende der Seite vs. der Abstand zum oberen Ende des Fensters. :-(
Der Yeti