gl03: toggle ".style.display" mit browserdetection

folgendes problem, das ich seit länger zeit (mit zugegeben beschränkten fähigkeiten) zu lösen versuche:

im idealfall soll sich durch click auf eine table-cell bei einer anderen die ".style.display" property von "none" auf "table-cell" aendern. das funktioniert bei Mozilla super, beim IE 5.5 + 6.0 scheitert es klaeglich. Verwende folgenden code (der Einfachheit halber auf die zwei faelle beschränkt):

function appear(obj) {

if (document.getElementById && !document.all){
      //Mozilla - funktioniert!
      pre = 'document.getElementById("';
      post = '").style';
   }
   if (document.getElementById && document.all){
      //IE 5.5+ - funktioniert nicht!
      pre = 'document.all.';
      post = '.style';
   }

var myLayer = eval(pre + obj + post);

if (myLayer.display == "none") {
    myLayer.display = "table-cell";
  }
  else {
    myLayer.display = "none";
  }
}

Im Body wird dann per 'onclick' die id uebergeben:

<TABLE>
<TR><TD><SPAN CLASS="hl" id="gigshead" onMouseOver="this.style.cursor = 'pointer'" onclick="appear('gigs');">GIGS</SPAN><BR></TD></TR>

<TR align="left"><TD id="gigs" style="display:none" CLASS="text" NOWRAP>blablabla
</TD></TR></TABLE>

Der Fehler sollte nicht bei der Browser detection liegen, sondern in der 'if (myLayer.display...' zeile - IE meint 'Could not get the display property. Invalid argument.'

Noch was: wenn ich "display" in der table-cell auf "table-cell" als Ausgangsposition setze statt auf "none", kann ich sie korrekt zum verschwinden bringen, der fehler kommt nur wenn display == none!

Besten Dank fuer jede mögliche Hilfe,

Georg.

  1. Hi,

    if (myLayer.display == "none") {
        myLayer.display = "table-cell";

    damit ist der IE leider komplett überfordert.
    table-cell kennt er nicht.

    cu,
    Andreas

    --
    MudGuard? Siehe http://www.Mud-Guard.de/
    Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. if (myLayer.display == "none") {
          myLayer.display = "table-cell";

      damit ist der IE leider komplett überfordert.
      table-cell kennt er nicht.

      :O das erklaert ja einiges - allerding bin ich mir ziemlich sicher, dass IE 5.0 den mozilla code richtig interpretiert hat - 5.X fuer MAC tut's auf alle faelle!

      "inline" interpretiert wieder Mozilla nicht richtig, also de facto 2 versionen noetig.

      besten dank,

      georg.-

  2. Hi,

    im idealfall soll sich durch click auf eine table-cell bei einer anderen die ".style.display" property von "none" auf "table-cell" aendern.

    Versuch statt "table-cell" für den IE "block"!

    Gruß, Cybaer

    PS: Vielleicht ist http://Coding.vampirehost.de/Toggle für Dich von Interesse.

    --
    Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe auch Anderen: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
  3. Hallo,

    »block« funktioniert wie gesagt für den MSIE. Das ist der interne display-Wert für Zellen (siehe zellenelementknoten.currentStyle.display). Die möglichen display-Werte stehen auch hier: http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/display.asp.

    Darüber hinaus:

    function appear(obj) {

    if (document.getElementById && !document.all){
          //Mozilla - funktioniert!
          pre = 'document.getElementById("';
          post = '").style';
       }
       if (document.getElementById && document.all){
          //IE 5.5+ - funktioniert nicht!
          pre = 'document.all.';
          post = '.style';
       }

    var myLayer = eval(pre + obj + post);

    if (myLayer.display == "none") {
        myLayer.display = "table-cell";
      }
      else {
        myLayer.display = "none";
      }
    }

    1. eval() ist unnötig und ineffizient. Bei getElementById brauchst du eval gar nicht (document.getElementById(obj)) und bei document.all auch nicht (document.all[obj], siehe http://selfhtml.teamone.de/javascript/objekte/all.htm#mit_namen_ansprechen).

    2. Die Browserweiche ist widersinnig: IE 5.x+ kannst du ebenfalls über getElementById versorgen, daher ist die Weiche an der Stelle unnötig. Sie wäre höchstens nötig, wenn du auch IE 4 versorgen willst. Dann ist aber document.getElementById && document.all keine angemessene Bedingung.

    3. Mit document.all lässt sich nicht zuverlässig MSIE erkennen. Opera kennt document.all auch (was in obigem Fall nicht schlimm ist, was aber eine Rolle spielt, wenn es darum geht, zu unterscheiden, wer table-cell und wer block bekommt).

    Ich würde es so lösen:

    function appear (id) {
     if (document.getElementById) {
      var myLayer = document.getElementById(id);
     } /* else if (document.all) var myLayer = document.all[id]; */
     if (window['display'+id]) { // in displayXXX wird der Status gespeichert (true=sichtbar/false=unsichtbar)
      myLayer.style.display = 'none';
      window['display'+id]=false;
     } else {
      if (document.uniqueID) {
       myLayer.style.display = 'block';
      } else {
       myLayer.style.display = 'table-cell';
      }
      window['display'+id]=true;
     }
    }

    Mit document.uniqueID soll MSIE 5.x+ identifiziert werden. Denkbar wäre auch meines Wissens document.all && !window.opera.

    Der Fehler sollte nicht bei der Browser detection liegen, sondern in der 'if (myLayer.display...' zeile - IE meint 'Could not get the display property. Invalid argument.'

    Das weißt du ja mittlerweile: Er erkennt »table-cell« nicht als gültigen Wert für display an.

    Noch was: wenn ich "display" in der table-cell auf "table-cell" als Ausgangsposition setze statt auf "none", kann ich sie korrekt zum verschwinden bringen, der fehler kommt nur wenn display == none!

    Klar, weil er style="display:table-cell" aus oben genannten Gründen vollkommen ignoriert. Somit liefert .style.display einen leeren String zurück. Spätestens beim Umschalten auf table-cell kommt aber der obige Fehler.

    Mathias