André Laugks: Mozilla/Firefox: Scriptfehler bei setzen einer StyleEigenschaft

Hallo!

Ich habe folgendes Script, welches nach den Laden der Seite DIV's über display:none; verstecken soll.

Ich bekomme aber eine Fehlermeldung die ich mir nicht ganz erklären kann:
Fehler: document.getElementById("a" + ebene) has no properties
Quelldatei: test.html Zeile: 19

Zeile: 19 document.getElementById('a' + ebene).setAttribute("style","display:none;");

test.html

<html>
<head>
 <script language="JavaScript">
 <!--

function init()
    {
     fragen = document.getElementById("liste").childNodes.length;
     for(var i = 1; i <= fragen; i++)
      {
       if(document.getElementById)
        {
         anzeigen_zu(i);
        }
      }
    }

function anzeigen_zu(ebene)
    {
         document.getElementById('a' + ebene).setAttribute("style","display:none;");
    }
 //-->
 </script>
</head>

<body onload="init();">

<div id="liste">
 <div id="f1">
  <div id="a1" style="display:block;">A1</div>
 </div>
 <div id="f2">
  <div id="a2" style="display:block;">A2</div>
 </div>
 <div id="f3">
  <div id="a3" style="display:block;">A3</div>
 </div>
</div>

</body>
</html>

MfG, André Laugks

--
L-Andre @ gmx.de
  1. Hi,

    <html>
    <head>
    <script language="JavaScript">
    <!--

    function init()
        {
         fragen = document.getElementById("liste").childNodes.length;

    Das gibt die Anzahl aller Kindknoten. Die ist deutlich höher als die der Kind-Elemente (mit ner id ax) - es gibt ja auch noch die Textknoten ...

    <div id="liste">
    <div id="f1">
      <div id="a1" style="display:block;">A1</div>
    </div>

    Warum benutzt Du div-Suppe, wenn Du eine Liste haben willst?

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    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. Nabend André!

      noch etwas, was man verbesser könnte:

      <html>
      <head>
      <script language="JavaScript">
      <!--

      function init()
          {
           fragen = document.getElementById("liste").childNodes.length;
           for(var i = 1; i <= fragen; i++)
            {
             if(document.getElementById)

      // die Abfrage kommt viel zu spät
      // zwei Zeilen davor greifst Du doch
      // schon darauf zurück

      {
               anzeigen_zu(i);
              }
            }
          }

      Gruß aus Berlin!
      eddi

      1. Hallo!

        noch etwas, was man verbesser könnte:

        Da muß ich Dir recht geben!

        MfG, André Laugks

        --
        L-Andre @ gmx.de
    2. Hallo!

      Das gibt die Anzahl aller Kindknoten. Die ist deutlich höher als die der Kind-Elemente (mit ner id ax) - es gibt ja auch noch die Textknoten ...

      Ich weiss :-)! Ich war eben nur zu matschig im Kopf!

      Warum benutzt Du div-Suppe, wenn Du eine Liste haben willst?

      Ich habe den Rest der noch so im Quellentext steht raus genommen. wie schon gesagt, war ich matschig im Kopf und konnte mir nicht recht erklären woher der Fehler kommt.

      MfG, André Laugks

      --
      L-Andre @ gmx.de
  2. Hallo André,

    Das Problem liegt m. E. darin, dass wenn die Funktion aufgerufen wir, die Elemente noch nicht existieren. Versuchs mal, dass, Du die Funktion erst ziemlich am Ende der Datei aufrufst.

    Gruß,

    Dieter

  3. Huhu

    for(var i = 1; i <= fragen; i++)

    warum fängst Du hier mit 1 an?

    Wie MudGuard schon schrieb bedenke dass auch Whitespace, Kommentare und Text
    als Knoten behandelt werden.

    Guck mal nach nodeType, z.B. in dieser Referenz.

    http://www.mozilla.org/docs/dom/domref/
    http://www.mozilla.org/docs/dom/domref/dom_el_ref16.html#1027946

    Viele Grüße

    lulu

    --
    bythewaythewebsuxgoofflineandenjoytheday
  4. Hi André,

    Ich würde mir in diesem Fall das Knotengedöns gar nicht geben, sondern einfach alle Divs durchlaufen:

    function init()
    {
        divs = document.getElementsByTagName('div');
        for(var i = 0; i < divs.length; i++)
        {
            divID = divs[i].getAttribute('id');
            if(divID && divID.indexOf('a') != -1)
            {
                anzeigen_zu(divID);
            }
        }
    }

    function anzeigen_zu(ebene)
    {
        document.getElementById(ebene).style.display = 'none';
    }

    MfG, Mülli

    --
    Viva Colonia!
    1. Meistro!

      Ich würde mir in diesem Fall das Knotengedöns gar nicht geben, sondern einfach alle Divs durchlaufen:

      Dieses ganze Kontengedöns ist sonst kein Problem, nur heute eben. Selbst so eine lumpige IF-Abfrage war eben eine Geburt.

      function init()
      {
          divs = document.getElementsByTagName('div');
          for(var i = 0; i < divs.length; i++)
          {
              divID = divs[i].getAttribute('id');
              if(divID && divID.indexOf('a') != -1)
              {
                  anzeigen_zu(divID);
              }
          }
      }

      Finde ich eine gute Idee.

      MfG, André Laugks

      --
      L-Andre @ gmx.de
      1. Hi André,

        Meistro!

        Bist nicht du das? ;-)

        Dieses ganze Kontengedöns ist sonst kein Problem, nur heute eben. Selbst so eine lumpige IF-Abfrage war eben eine Geburt.

        In solchen Fällen hilft manchmal ein kühles Kölsch. :-)

        MfG, Mülli

        --
        Viva Colonia!
    2. Hallo,

      function init()
      {
          divs = document.getElementsByTagName('div');
          for(var i = 0; i < divs.length; i++)
          {
              divID = divs[i].getAttribute('id');
              if(divID && divID.indexOf('a') != -1)
              {
                  anzeigen_zu(divID);

      Hier kann man der Funktion auch einfach divs[i] übergeben...

      function anzeigen_zu(ebene)
      {
          document.getElementById(ebene).style.display = 'none';

      ...dann kann man sich das getElementById hier sparen.
      Ändert nichts an der Funktionalität, ist nur geringfügig schneller. Ich weise darauf hin, weil es guter Stil ist, der sich auszahlt, wenn die Programmierung komplexer wird. Man sollte auch darauf achten, dass Variablen immer einen festgelegten Geltungsbereich haben. So sollten divs und divID mit »var« deklariert werden, damit sie nur innerhalb der Funktion gelten. (Das ist hier speziell auch nur eine Frage des sauberen Programmierens.)
      Übrigens sollen hier ja nur alle div-Elemente im div-Element mit der ID »liste« durchlaufen werden. Dazu könnte man document.getElementById("liste").getElementsByTagName("div") verwenden. (Auch eine Spitzfindigkeit...)

      Mathias

      1. Hallo molily,

        Ändert nichts an der Funktionalität, ist nur geringfügig schneller. Ich weise darauf hin, weil es guter Stil ist, der sich auszahlt, wenn die Programmierung komplexer wird. Man sollte auch darauf achten, dass Variablen immer einen festgelegten Geltungsbereich haben. So sollten divs und divID mit »var« deklariert werden, damit sie nur innerhalb der Funktion gelten. (Das ist hier speziell auch nur eine Frage des sauberen Programmierens.)
        Übrigens sollen hier ja nur alle div-Elemente im div-Element mit der ID »liste« durchlaufen werden. Dazu könnte man document.getElementById("liste").getElementsByTagName("div") verwenden. (Auch eine Spitzfindigkeit...)

        Hätte ich das Script geschrieben, um es in den "Betrieb zu nehmen", hätte ich das Ganze genauso umgesetzt, wie du beschrieben hast. ;-) Da ich das aber basierend auf Andrés Vorlage einfach so runtergekloppt habe, um meinen Problemlösungsansatz darzulegen, ist es halt leicht suboptimal geworden.

        Aber da ich weiss, dass man sich bei André um guten Stil bzw. optimalen Code eigentlich keine Gedanken machen muss, war mir das auch nicht besonders wichtig.

        Aber vielleicht sollte ich in Zukunft dazu schreiben, wenn ich unoptimierten Code poste. Für einen Anfänger, der den Thread liest wäre das sicherlich hilfreich.

        Hmm. In drei Absätzen habe ich jeweils ein "aber" untergebracht. Das liest sich ja garnicht schön. Aber was solls... ;-)

        MfG, Mülli

        --
        Viva Colonia!
        1. Aber vielleicht sollte ich in Zukunft dazu schreiben, wenn ich unoptimierten Code poste. Für einen Anfänger, der den Thread liest wäre das sicherlich hilfreich.

          Hi, ich als Anfänger habe das sowieso nicht richtig verstanden :-))