Matze: bei Klick nächstes Element ausblenden

Hallo,

ich habe eine Überschrift und darunter eine Liste.

  
<h3>Überschrift</h3>  
<ul>  
    <li>foo</li>  
    <li>bar</li>  
</ul>

Beim klick auf die Überschrift soll nun die Liste ausgeblendet werden.
An die Überschrift komm ich mit JS über target, aber ich weiß nicht wie ich die nachfolgende Liste ansprechen kann.
Ich habe es mit nextSibling versucht, aber da erhalte ich immer nur #text :(

function handleClicks(e){  
	var e=(window.event)?window.event:e;  
	var o=(window.event)?e.srcElement:e.target;  
	liste = o.nextSibling;  
        // dachte das funzt*  
        // liste.style.display = 'none';  
        // tut es aber nicht ;)  
	alert(liste);  
}  
window.document.addEventListener("click", handleClicks, false);

Könnte mir bitte jemand sagen wie ich an die <ul> komme?
Bin ich mit nextSibling auf dem richtigen Weg? Was mach ich falsch?

Danke und Grüße, Matze

  1. Ich habe es mit nextSibling versucht, aber da erhalte ich immer nur #text :(

    Works as desigend: Weil der nächste Knoten nach deinem h3-Element eindeutig ein Textknoten ist.

    Bin ich mit nextSibling auf dem richtigen Weg? Was mach ich falsch?

    Entweder du klebst du h3 und das ul-Element ohne Whitespace zusammen oder du prüst, welchen Knotentyp nextSibling hat: Eenn es ein Elementknoten ist, blendest du aus, wenn nicht nimmst du dessen nächsten Nachfolger (rekursiv).

    1. Hallo suit!

      Works as desigend: Weil der nächste Knoten nach deinem h3-Element eindeutig ein Textknoten ist.

      Wieso? Nach meinem h3-Element kommt doch eindeutig eine Liste.

      Bin ich mit nextSibling auf dem richtigen Weg? Was mach ich falsch?
      Entweder du klebst du h3 und das ul-Element ohne Whitespace zusammen oder du prüst, welchen Knotentyp nextSibling hat: Eenn es ein Elementknoten ist, blendest du aus, wenn nicht nimmst du dessen nächsten Nachfolger (rekursiv).

      Ich wusste nicht, dass die Whitespaces hier eine Rolle spielen.
      Wenn ich </h3><ul> direkt aneinander schreibe, komm ich an die Liste. Sieht aber nicht sehr schön aus.

      So gefällt es mir besser:

      liste = o.nextSibling;  
      while(liste.nodeName != 'UL'){  
          liste = liste.nextSibling;  
      }  
      liste.style.display = 'inline';
      

      Es funktioniert soweit wie es soll. Ich frag trotzdem nochmal, ob ich einen Fehler gemacht habe.

      Danke und Grüße, Matze

      1. Hallo Matze,

        liste = o.nextSibling;

        while(liste.nodeName != 'UL'){
            liste = liste.nextSibling;
        }
        liste.style.display = 'inline';

          
        du solltest sicherstellen, das zumindestens am Ende der Seite ein UL steht,  
          
        Gruß, Jürgen  
          
        PS:  [Elefantensuche](http://www.angelfire.com/moon/dotbrown/elefantensuche.htm)  
        
        
        1. Hallo Jürgen!

          du solltest sicherstellen, das zumindestens am Ende der Seite ein UL steht,

          Ähm sorry, aber wie mach ich das? Bzw. was passiert, wenn kein UL gefunden werden konnte? Dann bricht das Skript doch einfach irgendwann (spätestens am Ende des Dokuments) ab.

          Danke und Grüße, Matze

          1. Hallo Matze,

            Ähm sorry, aber wie mach ich das? Bzw. was passiert, wenn kein UL gefunden werden konnte? Dann bricht das Skript doch einfach irgendwann (spätestens am Ende des Dokuments) ab.

            ja, und zwar mit einen Fehler.

            Sorge dafür, das

            • immer ein Elefant ... äh ich meine ein UL da ist, oder
            • das Script nicht die ganze Seite abklappert, aber auch nicht zu wenig, und prüfe, ob es nextSibling noch gibt.

            Gruß, Jürgen

            1. Hallo Jürgen!

              • das Script nicht die ganze Seite abklappert, aber auch nicht zu wenig, und prüfe, ob es nextSibling noch gibt.

              Also prüfen ob nextSibling nicht null ist?!
              Zu verhindern, dass das Skript nicht die komplette Seite durchwühlt, reicht ein Element um die Überschrift und Liste, oder? Durch nextSibling sollte dann nur innerhalb des Kontainers gesucht werden, oder?

              Danke und Grüße, Matze

              1. Hallo Matze,

                Also prüfen ob nextSibling nicht null ist?!

                Ja

                Zu verhindern, dass das Skript nicht die komplette Seite durchwühlt, reicht ein Element um die Überschrift und Liste, oder?

                Es ist deine Seite, du musst wissen, wie viele Elemente zwischen Überschrift und Liste sein können.

                Durch nextSibling sollte dann nur innerhalb des Containers gesucht werden, oder?

                gibt es einen Container?

                Noch eine Idee:

                Du bündelst Überschrift und Liste in einem Container, z.B. einem div. Dann kommst du per parentNode zum Containerelement und per parentNode.getElementsByTagName("ul")[0] zur 1. Liste im Container.

                Noch eine weitere Idee:

                du gibst Überschrift und Liste eine Klasse: class="...". Dann suchst du nach der Überschrift mit der entsprechenden Klasse und gibst ihr den onclick-Handler, der die Liste mit der gleichen Klasse aus- oder einblendet.
                Beachte hierbei, dass du dir ein Browserübergreifendes "getElementsByClassName" selbst basteln oder suchen musst.

                Beide Ideen ungetestet.

                Gruß, Jürgen

                1. Hallo Jürgen,

                  die fertige Version fehlerfrei getestet im aktuellen Firefox und Opera:

                  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
                  <html xmlns="http://www.w3.org/1999/xhtml">  
                  <head>  
                  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
                  <title>Unbenanntes Dokument</title>  
                  <script type="text/javascript">  
                  // bei aktiviertem JS die Submenüs ausblenden  
                  window.onload = closeSubs;  
                  function closeSubs() {  
                  	subMenues = document.getElementById('menu').getElementsByTagName('ul');  
                  	for(i = 0; i < subMenues.length; i++){  
                  		// offene Submenüs schließen  
                  		subMenues[i].style.display = 'none';  
                  	}  
                  }  
                  function handleClicks(e){  
                  	var e=(window.event)?window.event:e;  
                  	var o=(window.event)?e.srcElement:e.target;  
                  	if(o.className == 'submenuHeader'){  
                  		// gewählten Menüpunkt aufklappen  
                  		liste = o.nextSibling;  
                  		while(liste.nodeName != 'UL' || liste.nextSibling == null){  
                  			liste = liste.nextSibling;  
                  		}  
                  		status = liste.style.display;  
                  		closeSubs();  
                  		if(status == 'block'){  
                  			liste.style.display = 'none';  
                  		}else{  
                  			liste.style.display = 'block';  
                  		}  
                  	}  
                  }  
                  window.document.addEventListener("click", handleClicks, false);  
                  </script>  
                  <style type="text/css">  
                  ul#menu {  
                      list-style-type:none;  
                      width:200px;  
                      background:#CCC;  
                      padding:0;  
                  }  
                  ul#menu li {  
                      padding:2px 2px 2px 20px;  
                      background:url(bottom.png) no-repeat left bottom;  
                  }  
                  ul#menu li.submenu {  
                      padding-left:0;  
                      padding-bottom:0;  
                      /* anderer Unterstrich (Hintergrundbild) für Ende von Submenüs */  
                      /* background:url(deinBild) no-repeat left bottom; */  
                  }  
                  ul#menu li.submenu h3 {  
                      cursor:pointer;  
                      padding:0 0 2px 20px;  
                      margin:0;  
                      font-size:1em;  
                      font-weight:normal;  
                      background:url(bottom.png) no-repeat left bottom;  
                  }  
                  .submenuList {  
                      display:block;  
                  }  
                  ul#menu li.submenu ul {  
                      list-style-type:none;  
                      padding:0 0 0 20px;  
                  }  
                  ul#menu li.submenu ul li{  
                      padding:2px 2px 2px 20px;  
                      /* anderer Unterstrich (Hintergrundbild) für Submenüs */  
                      /* background:url(deinBild) no-repeat left bottom; */  
                  }  
                  ul#menu li.submenu ul li.noBg {  
                      background-image:none;  
                  }  
                  </style>  
                  </head>  
                    
                  <body>  
                  <ul id="menu">  
                  	<li>Startseite</li>  
                      <li>Menüpunkt</li>  
                      <li class="submenu">  
                      	<h3 class="submenuHeader">Menüpunkt mit Submenü</h3>  
                          <ul class="submenuList">  
                          	<li>Menüpunkt</li>  
                      		<li class="noBg">Menüpunkt</li>  
                          </ul>  
                      </li>  
                      <li>Menüpunkt</li>  
                      <li class="submenu">  
                      	<h3 class="submenuHeader">Menüpunkt mit Submenü</h3>  
                          <ul class="submenuList">  
                          	<li>Menüpunkt</li>  
                      		<li class="noBg">Menüpunkt</li>  
                          </ul>  
                      </li>  
                  </ul>  
                  </body>  
                  </html>
                  

                  bottom.png ist bei mir ein 1px hoher Streifen mit teilweiser Alpha-Transparenz.

                  Irgendwelche Einwände?

                  Grüße, Matze

                  1. Hallo Matze,

                    die fertige Version fehlerfrei getestet im aktuellen Firefox und Opera:

                    die anderen Browser aber nicht vergessen.

                      while(liste.nodeName != 'UL' || liste.nextSibling == null){  
                    

                    wenn ich das richtig verstehe, läuft die Schleife, wenn das Element kein UL ist, oder wenn du am Ende bist. Teste es mal, wenn kein UL im Dokument ist. Meiner Meinung nach müsste die Schleife so aussehen:

                    while(liste.nodeName != 'UL' && liste.nextSibling){
                          __________  __________    _______  ________
                                    /                     /
                                false bei UL          false am Ende

                    Da bei UND beide Bedingungen true sein müssen, bricht die Schleife ab, wenn nodeName gleich UL ist oder das Ende des Dokuments erreicht ist.

                    Gruß, Jürgen

                    1. Hallo Jürgen,

                        while(liste.nodeName != 'UL' || liste.nextSibling == null){  
                      

                      while(liste.nodeName != 'UL' && liste.nextSibling){

                      ach Gott, was hab ich denn da gemacht. Ok, war auch schon spät.
                      Du hast natürlich völlig recht.
                      Danke, ich hätte nicht nochmal drüber geschaut.

                      Grüße, Matze

      2. Hi,

        Works as desigend: Weil der nächste Knoten nach deinem h3-Element eindeutig ein Textknoten ist.
        Wieso? Nach meinem h3-Element kommt doch eindeutig eine Liste.

        ja, aber nicht *direkt* danach. Erst kommt eine Text-Node.

        Ich wusste nicht, dass die Whitespaces hier eine Rolle spielen.

        Eswärefatal,siezuignorieren.Äußerstfatal.

        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. Hallo Cheatah,

          ja, aber nicht *direkt* danach. Erst kommt eine Text-Node.

          also wird ein z.b. Leerzeichen bereits als Text erkannt?!

          Ich wusste nicht, dass die Whitespaces hier eine Rolle spielen.
          Eswärefatal,siezuignorieren.Äußerstfatal.

          Hehe sehr treffend :)
          Meine Annahme war eher die, dass ich mit JS DOM-Elemente bearbeite.
          Was dazwischen an Whitespaces ist spielt wie im HTML keine (selten eine) Rolle.

          Grüße, Matze

          1. Hi,

            ja, aber nicht *direkt* danach. Erst kommt eine Text-Node.
            also wird ein z.b. Leerzeichen bereits als Text erkannt?!

            natürlich. Außer in älteren IEs - die haben vermutlich den grauen Star.

            Meine Annahme war eher die, dass ich mit JS DOM-Elemente bearbeite.

            Korrekt. Wobei die Bezeichnung "DOM-Objekte" lauten muss. Zwar gibt es in DOM Element-Objekte, aber keine Elemente an sich.

            Was dazwischen an Whitespaces ist spielt wie im HTML keine (selten eine) Rolle.

            Es spielt in HTML eine Rolle, und es sind DOM-Objekte.

            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. Meine Annahme war eher die, dass ich mit JS DOM-Elemente bearbeite.

              Korrekt. Wobei die Bezeichnung "DOM-Objekte" lauten muss. Zwar gibt es in DOM Element-Objekte, aber keine Elemente an sich.

              Afaik heisst es DOM-Knoten (Nodes), und die haben verschiedene Typen - Text, Kommentar, Element, Attribut usw.

              1. Hi,

                Afaik heisst es DOM-Knoten (Nodes),

                richtig, in JavaScript werden sie repräsentiert durch Objekte.

                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
  2. Om nah hoo pez nyeetz, Matze!

    was hältst du von CSS-Nachfahrenselektoren?

    Matthias

    --
    http://www.billiger-im-urlaub.de/kreis_sw.gif
    1. was hältst du von CSS-Nachfahrenselektoren?

      Was hilft das nun bei einem JavaScript-/DOM-Problem?

      Eine Selektor-Engine (z.B. Sizzle) mit 8 KiB einrichten, damit man keine 5 Zeilen JS per Hand schreiben muss? :D

      1. Om nah hoo pez nyeetz, suit!

        Was hilft das nun bei einem JavaScript-/DOM-Problem?

        Vielleicht habe ich es ja auch falsch verstanden, aber bei dieser Struktur

        <h3>Überschrift</h3>
        <ul>
            <li>foo</li>
            <li>bar</li>
        </ul>
        

        sollte das Ausblenden der Liste auch ohne JS möglich sein.

        Matthias

        --
        http://www.billiger-im-urlaub.de/kreis_sw.gif
        1. sollte das Ausblenden der Liste auch ohne JS möglich sein.

          Ja, aber nicht das dauerhafte ein und ausblenden.

          Das ausblenden alle Elemente nach einer Überschrift und das gezielte Einblenden mittels ::target wäre eine Möglichkeit. Ist aber weit nicht so flexibel wie eine JavaScript-Lösung.

    2. Hi,

      was hältst du von CSS-Nachfahrenselektoren?

      für das genannte Problem gar nichts.
      Schließlich ist die ul ja kein Nachfahre der Überschrift, sondern nur ein Nachbar.

      cu,
      Andreas

      --
      Warum nennt sich Andreas hier MudGuard?
      O o ostern ...
      Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
      1. Om nah hoo pez nyeetz, MudGuard!

        Hi,

        was hältst du von CSS-Nachfahrenselektoren?

        für das genannte Problem gar nichts. Schließlich ist die ul ja kein Nachfahre der Überschrift, sondern nur ein Nachbar.

        Wieder ein typisches Beispiel von unbedachtem Schreiben, aber der Link ist wenigstens richtig. h1 + ul selektiert die Liste.

        Matthias

        --
        http://www.billiger-im-urlaub.de/kreis_sw.gif