Martin Lenzelbauer: firstChild.nextSibling im IE

Hallo!

Ich habe leider noch keinen Eintrag gefunden, der mein Problem behandelt hätte. Ich habe eine Tabelle, in welcher sich in jeder Zelle ein Link befindet. Nun möchte ich mit JS die Hintergrundfarbe der Zelle ändern, sowie die Schriftfarbe des Links. Das funktioniert auch ganz gut in allen Browsern - bis auf den Internet Explorer.
Hier mein Script:

function rollOut(id){
  if(id != activeFrame){
    document.getElementById(id).style.backgroundColor = "#FFFFFF";
    document.getElementById(id).firstChild.nextSibling.style.color = "#BDBDAD";
  }
}

Die Id ist die id der Zelle. Das Setzen der Hintergrundfarbe funktioniert auch, nur wenn ich den Inhalt des Zelle (den Link) mit firstChild.nextSibling ansprechen will, weigert sich der Internet Explorer.

Jemand eine Idee?

MfG, Martin

  1. Hallo Martin,

    function rollOut(id){
      if(id != activeFrame){
        document.getElementById(id).style.backgroundColor = "#FFFFFF";
        document.getElementById(id).firstChild.nextSibling.style.color = "#BDBDAD";
      }
    }

    Anders als Opera und Mozilla interpretiert der IE Zeilenumbrüche im Quellcode nicht als eigenständige Textknoten. Beim IE musst du also ggf. auf nextSibling verzichten. Beim IE am Mac mag es aber wieder anders aussehen.

    Gruß Gernot

    1. Hey, danke, das funktioniert wunderbar. Da wär ich wohl noch lange bis ewig gesessen, um da draufzukommen...

      Danke!

      Anders als Opera und Mozilla interpretiert der IE Zeilenumbrüche im Quellcode nicht als eigenständige Textknoten. Beim IE musst du also ggf. auf nextSibling verzichten. Beim IE am Mac mag es aber wieder anders aussehen.

      Gruß Gernot

      1. Hallo Martin,

        Hey, danke, das funktioniert wunderbar. Da wär ich wohl noch lange bis ewig gesessen, um da draufzukommen...

        Anders als Opera und Mozilla interpretiert der IE Zeilenumbrüche im Quellcode nicht als eigenständige Textknoten. Beim IE musst du also ggf. auf nextSibling verzichten. Beim IE am Mac mag es aber wieder anders aussehen.

        Ingo hat dir ja inhaltlich dasselbe gesagt.

        Wie hast du es denn jetzt gelöst? An welche If-Abfrage hast du die Enscheidung, ob du jetzt childNodes[0] oder childnodes[1] ansprichst geknüpft? Da kann man nämlich in böse Fallen laufen. Darf man mal Code sehen?

        Gruß Gernot

        1. Hallo Gernot!

          Ingo hat dir ja inhaltlich dasselbe gesagt.

          Wie hast du es denn jetzt gelöst? An welche If-Abfrage hast du die Enscheidung, ob du jetzt childNodes[0] oder childnodes[1] ansprichst geknüpft? Da kann man nämlich in böse Fallen laufen. Darf man mal Code sehen?

          Gruß Gernot

          Ich hab einfach eine Abfrage gemacht, ob es das Objekt gibt:

          if(document.getElementById(id).firstChild.nextSibling != null){
             document.getElementById(id).childNodes[1].style.color = "#FFFFFF";
          }
          else{
             document.getElementById(id).childNodes[0].style.color = "#FFFFFF";
          }

          Haut jedenfalls bei allen Browsern (IE, Firefox, Opera) hin!

          Martin

          1. Hallo Martin.

            if(document.getElementById(id).firstChild.nextSibling != null)

            IMHO reicht das hier:

            if(document.getElementById(id).firstChild.nextSibling)

            Gruß, Ashura

            --
            Selfcode: sh:( fo:) ch:? rl:( br:^ n4:& ie:{ mo:) va:) de:> zu:) fl:( ss:| ls:[ js:|
            30 Days to becoming an Opera8 Lover -- Day 15: Mouse Gestures
            Meine Browser: Opera 8.0 | Firefox 1.0.4 | Lynx 2.8.3 | Netscape 4.7 | IE 6.0
            IE Layout-Workaround №1: <!--[if IE]><style type="text/css">*{display:none;}</style><![endif]-->
          2. Hallo Martin,

            Ich hab einfach eine Abfrage gemacht, ob es das Objekt gibt:

            if(document.getElementById(id).firstChild.nextSibling != null){
               document.getElementById(id).childNodes[1].style.color = "#FFFFFF";
            }
            else{
               document.getElementById(id).childNodes[0].style.color = "#FFFFFF";
            }

            Aber was ist, wenn dir mal einfällt einen HTML-Kommentar einzufügen oder vielleicht zwei Returns hintereinander im Quellcode?

            Hat das erste Kind-Element, das du dir greifen willst, einen bestimmten TagName? Dann geh lieber über

              
            document.getElementById(id).getElementsByTagNames('deinTagName')[0]  
            
            

            ansonsten mach es so:

              
            var i=0;  
            while(document.getElementById(id).childNodes[i].nodeName=='#text'  
            || document.getElementById(id).childNodes[i].nodeName=='#comment') {  
              i++;  
            }  
            document.getElementById(id).childNodes[i].style.color = "#FFFFFF";  
            
            

            Gruß Gernot

            1. Hi,

              Aber was ist, wenn dir mal einfällt einen HTML-Kommentar einzufügen oder vielleicht zwei Returns hintereinander im Quellcode?

              Ich verstehe ja nicht, wieso man alles mögliche und unmögliche berücksichtigen soll und überhaupt diese ganzen Umstände mit dem Javascript macht. es spricht doch absolut nichts dagegen, einfach an diesen Stellen auf Whitespace (oder andere Knoten) zu verzichten.
              Keine Fehler, sparsameres Javascript und nebenbei ein paar Byte HTML gespart.

              freundliche Grüße
              Ingo

              1. Hallo Ingo,

                Ich verstehe ja nicht, wieso man alles mögliche und unmögliche berücksichtigen soll und überhaupt diese ganzen Umstände mit dem Javascript macht. es spricht doch absolut nichts dagegen, einfach an diesen Stellen auf Whitespace (oder andere Knoten) zu verzichten.
                Keine Fehler, sparsameres Javascript und nebenbei ein paar Byte HTML gespart.

                Ja, da hast du sicher Recht, wenn du dir sicher bist, dass du immer der Einzige bist, der die Seite pflegt. Das bist du aber in einem Team nicht, und dem nächsten könnte einfallen, hie und da mal ein zusätzliches Return oder einen HTML-Kommentar in den Code einzufügen.

                Das sagt dir jemand, der noch nie wirklich in einem Team gearbeitet hat, - leider!

                Gruß Gernot

                1. Hi,

                  Das bist du aber in einem Team nicht, und dem nächsten könnte einfallen, hie und da mal ein zusätzliches Return oder einen HTML-Kommentar in den Code einzufügen.

                  Der merkt dann aber schnell, daß er das nicht hätte tun sollen. ;-)
                  Aber dagegen hilft auch, ein paar der eingesparten Bytes für einen warnenden Kommentar über der Tabelle zu nutzen.

                  freundliche Grüße
                  Ingo

                  1. Hallo Ingo,

                    Der merkt dann aber schnell, daß er das nicht hätte tun sollen. ;-)
                    Aber dagegen hilft auch, ein paar der eingesparten Bytes für einen warnenden Kommentar über der Tabelle zu nutzen.

                    Deshalb bin ich froh, dass wir diese beiden gleichberechtigten Alternativen jetzt hier mal fürs Archiv protokolliert haben. Wichtig ist, man denkt ggf. (Team) an mindestens eine!

                    Gruß Gernot

            2. Hallo,

              var i=0;
              while(document.getElementById(id).childNodes[i].nodeName=='#text'
              || document.getElementById(id).childNodes[i].nodeName=='#comment') {
                i++;
              }
              document.getElementById(id).childNodes[i].style.color = "#FFFFFF";

                
              Bei solchen Operationen sollte man sich übrigens angewöhnen, das Elementknotenobjekt, das getElementById zurückgibt (vielleicht hier auch direkt .childNodes), in einer Variable zwischenzuspeichern. Das ist auf jeden Fall performanter als das erneute Ausführen von getElementById. Dann vielleicht als Abfrage kindknoten[i].nodeType == 1.  
                
              Mathias
              
              1. Hallo molily,

                Bei solchen Operationen sollte man sich übrigens angewöhnen, das Elementknotenobjekt, das getElementById zurückgibt (vielleicht hier auch direkt .childNodes), in einer Variable zwischenzuspeichern. Das ist auf jeden Fall performanter als das erneute Ausführen von getElementById. Dann vielleicht als Abfrage kindknoten[i].nodeType == 1.

                Wäre das nach deinem Geschmack ...

                  
                var kinder = document.getElementById(id).childNodes;  
                for (i=0;kinder[i].nodeType!=1;i++){}  
                kinder[i].style.color = "#FFFFFF";  
                
                

                ... oder ist das ein unerlaubter Missbrauch einer For-Schleife?

                Gruß Gernot

  2. Hi,

    Die Id ist die id der Zelle. Das Setzen der Hintergrundfarbe funktioniert auch, nur wenn ich den Inhalt des Zelle (den Link) mit firstChild.nextSibling ansprechen will, weigert sich der Internet Explorer.

    Du hast nicht zufällig Whitespace dazwischen?

    freundliche Grüße
    Ingo

  3. Hallo!

    Moin.

    function rollOut(id){
      if(id != activeFrame){
        document.getElementById(id).style.backgroundColor = "#FFFFFF";
        document.getElementById(id).firstChild.nextSibling.style.color = "#BDBDAD";
      }
    }
    Jemand eine Idee?

    Meine Idee wäre folgende:

      
    function rollOut(){  
     if (id != activeFrame)  
      with (document.getElementById(id)){  
       style.backgroundColor = "#FFFFFF"  
       getElementsByTagName('a')[0].style.color = "#BDBDAD"  
      }  
    }  
    
    

    MfG, Martin

    Hghzk
    T.