Sascha: Dynamisches Menu - Probleme mitChildNodes - IE vs FireFox

Guten Tag,

ich habe ein (hoffentlich) kleines Problem mit der Eigenschaft ChildNodes.

Auf dieser Seite findet ihr ein kleines Testmenu http://www.fallout-files.de/test_js.php

Jedes Untermenu hat eine eigene UL Liste.

Über die Punkte "Headline X" kann man die entsprechenden Untergruppen ein- bzw. ausklappen.

Dies funktioniert beim IE wie gewünscht. Nur der Firefox klappt z.B. keine weiteren Untergruppen sondern nur die LI-Elemente der "eigenen" UL Liste ein / aus.

Beispiel:

<ul id ='test0'>
   <li>
   <li>

<ul id = 'test1'>
       <li>
   </ul>

</ul>

Heißt das, dass konformerweise die Test1 Liste bzw. deren LI Elemnte keine Kinder der Test0 Liste darstellen und somit nich über document.getElementById(navigation_id).childNodes[i].tagName abrufbar sind?

Kann man irgendwo nachlesen, wer wessen Child sein darf?

Vielen Dank im Vorraus

Gruß Sascha

  1. Hallo,

    zunächst einmal ist Dein HTML-Grundgerüst nicht standardkonform. DTD für HTML sagt deutlich, dass nur <li>-Elemente im Element <ul> vorkommen dürfen. So sieht aber (vereinfacht) Dein HTML aus:

    <h3>Inhaltsverzeichnis</h3>  
    <ul id ='navigation_1' class ='ul'>  
     <li id ='menu_11'>Headline 1</li>  
     <li id ='menu_12'>ListItem 1 - 2 </li><li id ='menu_13'>ListItem 1 - 3</li>  
    </ul>  
    <ul id ='navigation_2' class ='ul'>  
     <li id ='menu_21'>Headline 2</li>  
     <li id ='menu_22'>ListItem 2 - 2</li>  
     <li id ='menu_23'>ListItem 2 - 3</li>  
     <li id ='menu_24'>ListItem 2 - 4</li>  
     <ul id ='navigation_3' class ='ul'>  
      <li id ='menu_31'>Headline 3</li>  
      <li id ='menu_32'>ListItem 3 - 1</li>  
      <li id ='menu_33'>ListItem 3 - 2</li>  
      <ul id ='navigation_4' class ='ul'>  
       <li id ='menu_41'>Headline 4</li>  
       <li id ='menu_42'>ListItem 4 - 2</li>  
       <li id ='menu_43'>ListItem 4 - 3</li>  
      </ul>  
     </ul>  
     <li id ='menu_25'>ListItem 2 - 5</li>  
    </ul>
    

    Es sind also regelwidriger weise <ul>-Elemente Kindelemente von <ul>-Elementen. (BTW: Die Klasse "ul" erscheint mir auch sehr sinnfrei, weil Elemente des selben Tags sich sowohl in CSS als auch in anderen Hinsichten auch ohne Klasse ansprechen lassen. Die Definition einer solchen ist also eine Dopplung.)

    Zu Deinen Fragen:

    Heißt das, dass konformerweise die Test1 Liste bzw. deren LI Elemnte keine Kinder der Test0 Liste darstellen und somit nich über document.getElementById(navigation_id).childNodes[i].tagName abrufbar sind?

    Ja.

    Kann man irgendwo nachlesen, wer wessen Child sein darf?

    Spezifikation HTML 4.01

    Gruß aus Berlin!
    eddi

    --
    "Ach! ...die größte Freud’
    ist doch die Zufriedenheit!!!"
    Wilhelm Busch und Multiple exclamation marks
    1. Hi,

      So sieht aber (vereinfacht) Dein HTML aus:

      was bitte ist einfach daran, dermaßen inflationär mit IDs und Klassen um sich zu schmeißen?

      Cheatah

      --
      X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
      X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes
      1. Hi Cheatah,

        So sieht aber (vereinfacht) Dein HTML aus:
        was bitte ist einfach daran, dermaßen inflationär mit IDs und Klassen um sich zu schmeißen?

        es wurde um einige Attribute und <script>-Elementen bereits von mir gegrützt. ^^

        Gruß aus Berlin!
        eddi

        --
        "Ach! ...die größte Freud’
        ist doch die Zufriedenheit!!!"
        Wilhelm Busch und Multiple exclamation marks
    2. Hallo Edgar,

      class = "ul" war nur eine Spielerei. Mir ist bewusst, dass ich das ul Tag auch direkt ansprechen kann.

      Dann werde ich mir etwas anderes überlegen müssen um mein Menu aufbauen zu können. Das Generieren über PHP / MySQL stellt nicht das Problem dar, sondern wie ich es über JS am elegantesten ansprechen kann :)

      Danke auch für den Link.

      Gruß Sascha

      1. Re:

        ...wie ich es über JS am elegantesten ansprechen kann :)

        var NodeArray=document.getElementById(navigation_id).getElementsByTagName('li');

        Gruß aus Berlin!
        eddi

        --
        "Ach! ...die größte Freud’
        ist doch die Zufriedenheit!!!"
        Wilhelm Busch und Multiple exclamation marks
        1. Re:

          ...wie ich es über JS am elegantesten ansprechen kann :)

          var NodeArray=document.getElementById(navigation_id).getElementsByTagName('li');

          Gruß aus Berlin!
          eddi

          Ich werde es ausprobieren. Besten Dank!

          Gruß Sascha

        2. Hallo Edgar!

          var NodeArray=document.getElementById(navigation_id).getElementsByTagName('li');

          "NodeArray" ist keine glückliche Namenswahl, da es sich nicht um ein Array handelt.

          Gruß Uwe

          1. Hallo,

            Hallo Edgar!

            var NodeArray=document.getElementById(navigation_id).getElementsByTagName('li');

            "NodeArray" ist keine glückliche Namenswahl, da es sich nicht um ein Array handelt.

            Das ist nach ECMA zwar richtig, weil bis auf primitive Werte alles Objekte sind, was Du wiederum unglücklicherweise verschweigst, soll hier aber einen möglichen Stolperstein für Sascha im Vorfeld aufzeigen.

            Gruß aus Berlin!
            eddi

            --
            "Ach! ...die größte Freud’
            ist doch die Zufriedenheit!!!"
            Wilhelm Busch und Multiple exclamation marks
            1. Hallo Edgar!

              var NodeArray=document.getElementById(navigation_id).getElementsByTagName('li');

              "NodeArray" ist keine glückliche Namenswahl, da es sich nicht um ein Array handelt.

              Das ist nach ECMA zwar richtig, weil bis auf primitive Werte alles Objekte sind, was Du wiederum unglücklicherweise verschweigst, soll hier aber einen möglichen Stolperstein für Sascha im Vorfeld aufzeigen.

              Keine Ahnung, was du mir damit sagen willst.

              Wie gesagt, der Rückgabewert der DOM-Methode »getElementsByTagName()« ist kein Array oder wenn dir das lieber ist, kein Arrayobjekt. Und deswegen eben - unglückliche Namenswahl.

              Gruß Uwe

              1. Re:

                Wie gesagt, der Rückgabewert der DOM-Methode »getElementsByTagName()« ist kein Array oder wenn dir das lieber ist, kein Arrayobjekt.

                Sondern was? Wo ist der Unterschied?

                Und deswegen eben - unglückliche Namenswahl.

                Unglücklich wäre für mich eine ungültige Namensvergabe, didaktisch kann man schon mit meiner Wahl leben. ;)

                Keine Ahnung, was du mir damit sagen willst.

                Macht nichts; mir ging es beim lesen Deines ersten Positings dieses Threads auch nicht anders. Aber keine Sorge, Korinthen mag ich.

                Gruß aus Berlin!
                eddi

                --
                "Ach! ...die größte Freud’
                ist doch die Zufriedenheit!!!"
                Wilhelm Busch und Multiple exclamation marks
                1. Hallo Edgar!

                  Wie gesagt, der Rückgabewert der DOM-Methode »getElementsByTagName()« ist kein Array oder wenn dir das lieber ist, kein Arrayobjekt.

                  Sondern was? Wo ist der Unterschied?

                  Eine »NodeList« bzw. eine »HTMLCollection«. Probier doch einfach mal die eine oder andere Arraymethode aus, dann wirst du schnell feststellen, dass du es nicht mit einem Array zu tun hast.

                  ... didaktisch kann man schon mit meiner Wahl leben. ;)

                  Deine Namenswahl suggeriert dem Fragesteller, dass er es mit einem Array, oh pardon - mit einem Arrayobjekt - zu tun hätte. Hat er aber nicht. Respekt - raffinierte didaktische Methode.

                  ... Korinthen mag ich

                  Na dann wünsch ich dir gutes Verdauen.

                  Gruß Uwe

                  P.S.: Lieber Edgar, ich will dir doch gar nichts Böses - also, immer schön ruhig bleiben.

                  1. Ach Uwe,

                    Gib doch einfach gleich brauchbare Infos, die anderen weiterhelfen, anstatt sie zu verwirren. Deine Spitzfindigkeit hat bis zu diesem Posting niemand verstanden (ehrlich gesagt glaube ich, dass sie selbst jetzt nur die wenigsten verstanden haben). Dann können andere auch davon lernen.

                    Mathias

                    1. Hallo Mathias!

                      Ach Uwe,
                      Gib doch einfach gleich brauchbare Infos, die anderen weiterhelfen, anstatt sie zu verwirren.

                      Jaaaa, es ist manchmal zum Verzweifeln mit mir. Frag mich :-)

                      Ich habe auf eine unglückliche Namenswahl hingewiesen und ich weiß in dem Moment nicht, ob das einfach nur ein Lapsus oder Unkenntnis ist.

                      Deine Spitzfindigkeit ...

                      Ich nehme dir - Mathias - diese Einschätzung in keinster Weise übel, aber ich teile sie nicht.

                      Ich weiß, dass du ein intrinsisches[1] JavaScript-Objekt von einem DOM-Objekt, wie »NodeList« bzw. »HTMLCollection«, unterscheiden kannst. Aber wer das nicht kann, der muss halt nachfragen - und ich bin der Letzte, denn ich neige durchaus zur Klugscheißerei, der sich dann einer Erklärung entzieht.

                      Aber denk dran, es kommt immer auch auf den Ton an, und der Ton von Edgar hat mir nicht gefallen.

                      Gruß Uwe

                      [1] Mist - jetzt habe ich diesen Ausdruck doch schon wieder benutzt ;-)

                      1. ...und ich bin der Letzte, denn ich neige durchaus zur Klugscheißerei, der sich dann einer Erklärung entzieht.
                        Aber denk dran, es kommt immer auch auf den Ton an, und der Ton von Edgar hat mir nicht gefallen.

                        Dann werde mir gegenüber (weil direkt) konkret!

                        Ich habe auf eine unglückliche Namenswahl hingewiesen und ich weiß in dem Moment nicht, ob das einfach nur ein Lapsus oder Unkenntnis ist.

                        Also warum fragst Du nicht exakt dies?

                        Ich denke, wir wedeln im Fachlichen von der gleichen Stelle. Aber beispielsweise sind wir mit dem Weihnachtsmann groß geworden, auch wenn es den unglücklicher weise gar nicht gibt. In dem Sinne weiß ich nicht, worauf nun Dein Zwang, hier einschreiten zu müssen, fußt.

                        Gruß aus Berlin!
                        eddi

                        --
                        "Ach! ...die größte Freud’
                        ist doch die Zufriedenheit!!!"
                        Wilhelm Busch und Multiple exclamation marks
                        1. Hallo Edgar!

                          Give a chance :-)

                          Es war einfach nur ein (gut gemeinter) Hinweis von mir. Nicht mehr und nicht weniger.

                          Dumm gelaufen der ganze Thread, aber so etwas passiert nun mal - selbst in den besten Familien. Also Friede - versuchen wir es beim nächsten Zusammentreffen besser zu machen :-)

                          Gruß Uwe

                      2. Hallo,

                        damit diese Debatte doch noch irgendeinen Sinn bekommt, versuchen wir mal, unser Wissen zu teilen. Ergänzungen willkommen!

                        Was ist der Unterschied zwischen einem Array, einer NodeList und einer HTMLCollection?

                        Ein Array ist ein Objekttyp aus dem JavaScript-Kern (ECMAScript). Man erzeugt sie über »new Array« oder mit der Literalschreibweise [ ... ]. Viele eingebaute JavaScript-Methoden geben Arrays zurück. Arrays sind vom Array-Konstruktor abgeleitet und haben daher die entsprechenden Methoden und Eigenschaften.

                        Eine NodeList ist ein Objekttyp aus dem W3C Document Object Model (Core). Es handelt sich um eine Liste von Knotenobjekte eines Dokumente, in erster Linie HTML-Elementobjekten. So eine Knotenliste erzeugt man üblicherweise nicht selbst, sondern bekommt sie von DOM-Methoden wie document.getElementsByTagName geliefert. Die Eigenschaft childNodes von Elementknoten liefert ebenfalls eine NodeList.

                        Diese NodeLists scheinen sich wie ein Array aufzuführen, sie sind es aber nur in einer Hinsicht: Sie haben eine Eigenschaft length und man kann die einzelnen Elemente in der Liste mit der Klammer-Schreibweise [index] ansprechen. Man kann sie also genauso wie einen Array durchlaufen:

                        for (var i = 0; i < nodelist.length; i++) { ... nodelist[i] ... }

                        Aber das ist schon alles, was sie mit Arrays gemeinsam hat. NodeList-Objekte haben nicht die anderen Methoden von Array-Objekten.

                        Intern wird nodelist[i] auf nodelist.item(i) umgeschrieben. Man kann also auch .item(i) schreiben, wenn man es länger will. Es ist zumindest interessant, dieses DOM- zu ECMAScript-Binding zu kennen. Denn item() verhält sich etwas anders als der Klammer-Operator [i] bei Arrays. item() liefert null zurück, wenn es kein Listenelement mit dem angegebenen Index gibt. Deshalb kann man NodeLists auch so durchlaufen:

                        for (var i = 0, element; element = nodelist[i]; i++) { ... element ... }

                        Da spart man sich die Zuweisung element = nodelist[i]; im Schleifenkörper. Denn wenn nodelist[i] null ergibt, ergibt auch die Zuweisung null und die Schleife bricht ab.
                        (Bei Arrays ist das prinzipiell auch möglich, aber nur wenn Arrays ausschließlich Elemente besitzen, die umgewandelt in Boolean true ergeben. Das ist bei NodeLists der Fall - sie enthalten Knoten und die sind Objekte und Objekte sind immer gleich true. Siehe dazu auch http://aktuell.de.selfhtml.org/artikel/javascript/objektabfragen/#boolean und http://aktuell.de.selfhtml.org/weblog/javascript-syntax.)

                        Eine HTMLCollection ist eine spezielle NodeList aus dem HTML-spezifischen DOM. Sie haben eine zusätzliche Methode, nämlich namedItem. namedItem() durchsucht die Liste nach einem Element, dessen Name oder ID mit dem Parameter übereinstimmt.  HTMLCollections erzeugt man üblicherweise nicht selbst, sondern gewisse DOM-HTML-Methoden bzw. -Eigenschaften ergeben HTMLCollections. Zum Beispiel sind document.images, document.forms, die elements-Eigenschaft bei form-Elementen, die rows-Eigenschaft bei table und die cells-Eigenschaft bei tr HTMLCollections.
                        namedItem() wird in JavaScript auf den Punkt-Operator zum Zugriff auf Unterobjekte (Property Accessor) umgeschrieben. htmlcollection.bla bzw. htmlcollection["bla"] wird zu htmlcollection.namedItem("bla") aufgelöst. Das kommt jetzt spanisch vor, ist uns aber gut bekannt von document.forms.formularname oder document.forms.formularname.elements["feldId"]. Jetzt wissen wir, wie diese Ausdrücke intern aufgelöst werden.

                        Diese spezifische Eigenschaft von HTMLCollections nützt vor allem bei der Suche nach Elementen mit einem bestimmten name-Attribute (z.B. document.forms.formular.elements.feld). Bei der Suche nach einer ID könnte man hingegen auch direkt document.getElementById verwenden und der Nutzen von namedItem ist gering.

                        Dann gibt es eine kleine Verwirrung: Verschiedene Browser verwenden HTMLCollections dort, wo eigentlich nur NodeLists spezifiziert sind. Z.B. ergibt document.getElementsByTagName im Firefox eine HTMLCollection, was eigentlich eine NodeList sein sollte.
                        Es hilft auch nicht wirklich weiter, dass Firefox in dem Fall standardwidrig auch die namedItem-Methode zur Verfügung stellt. Denn wenn man nach IDs suchen will, gibt es document.getElementById, wenn man dokumentweit bei allen Elementen nach Namen suchen will, gibt es document.getElementsByName. Eine Suche nach name-Attributen bei Elementen eines bestimmten Types kommt eher selten vor.
                        Solche nicht standardkonformen HTMLCollections sollte man daher wie NodeLists behandeln, dann kann man sich sicher sein, dass das Script browserübergreifend funktioniert.

                        Weitere Postings zum Thema:
                        http://forum.de.selfhtml.org/archiv/2006/9/t137474/#m893051
                        http://forum.de.selfhtml.org/archiv/2008/6/t172511/#m1130623

                        Mathias

                  2. Unten wirst Du mir vorwerfen, dass der Ton die Musik macht - aber bitte:

                    Respekt - raffinierte didaktische Methode.

                    Der Gegenvorschlag von Dir ist dann der Verweis auf die (gesamte) Sprachspezifikation, anstatt eine, genau betrachtet, hinkende Vereinfachung zu nutzen, und das bei jemanden der noch nicht mal strukturell so weit ist, mit validem HTML zu arbeiten? Respekt vor Deiner Methode! Aber wenigstens hast Du ja auf Nachfrage mal langsam ausgepackt.

                    P.S.: Lieber Edgar, ich will dir doch gar nichts Böses - also, immer schön ruhig bleiben.

                    Was soll mir das jetzt sagen? Was ich selber denk’ und tu’, trau’ ich andren Menschen zu? (Spekulier doch einfach nicht so wild ins Blaue, sondern lies nur das was wirklich dasteht! Und über post scripta habe ich schon so oft geschrieben...)

                    Gruß aus Berlin!
                    eddi

                    --
                    "Ach! ...die größte Freud’
                    ist doch die Zufriedenheit!!!"
                    Wilhelm Busch und Multiple exclamation marks
                    1. Hallo.

                      Und über post scripta habe ich schon so oft geschrieben...

                      MfG, at
                      P.S.: Was denn?