Konfusion: Ein- & Ausblenden über denselben Button / Parameter zurückgeben

Hi im Forum,

nach intensiver Durchforstung von SelfHTML inkl. Forum und WWW bin ich leider noch nicht auf die Lösung gestossen, jetzt frag ich einfach mal an:

Ich habe vier DIVs, davon darf immer nur eins eingeblendet sein. Die Funktion, beim Einblenden eines DIVs die anderen drei auszublenden läuft wunderbar.

Mein Problem ist, dass ich das offene DIV auch wieder ausblenden möchte, wenn ich auf den Button klicke, der dieses DIV geöffnet hat. In dem Fall wären dann alle vier DIVs wieder geschlossen. Ich müsste also irgendwo eine Info bereitstellen, welches DIV gerade geöffnet ist, also einen Parameter an die aufrufende Funktion zurückgeben.

Schaut Euch das mal an bitte. Könnt Ihr mir da helfen? So schwer kann das eigentlich nicht sein. Ich habe zuerst versucht, eine Variable "status" an den Event-Handler onClick zurückzugeben - funktioniert aber leider nicht:

<script type="text/javascript">
<!--
function klappe(id,status) {
  var wert;
  if ( status == 'zu' ) {
    wert = 'block';
    status = 'auf';
  } else {
    wert = 'none';
    status = 'zu';
  }
  document.getElementById(id).style.display = wert;
  return status;
}
//--></script>

<a href="#" onclick="klappe('aufklapptext1','zu')">Klicken</a>
<a href="#" onclick="klappe('aufklapptext2','zu')">Klicken</a>
<a href="#" onclick="klappe('aufklapptext3','zu')">Klicken</a>
<a href="#" onclick="klappe('aufklapptext4','zu')">Klicken</a>

Das war mein erster Versuch, anscheinend wird "status" nicht zu onClick durchgereicht <-- Ihr seht schon, bin JavaScript-Anfänger!
Der Schleifendurchlauf zum Schließen war hier eh noch nicht eingebaut - erstmal egal.

Jetzt bin soweit, dass die Schleife läuft, habe die Statusinformation zur Abfrage in eine andere Funktion augelagert, die Abfrage läuft aber nicht.
Hier das Script, ich bin sehr gespannt, welche (Denk-)Fehler ich da habe:

<script type="text/javascript">
<!--
function aufklapp_merker(x,aufgabe) {
  var offen;
  var check;
  var angefragt = x;
  if ( aufgabe == "merken" ) {
    offen = x;
  } else if ( aufgabe == "checken" ) {
    if ( angefragt == offen ) {
      check = "ja";
    } else {
      check = "nein";
    }
    return check;
  }
}

function aufklappen(n) {
  var klappreihe = new Array("empty","aufklapptext1","aufklapptext2","aufklapptext3","aufklapptext4");
  var aktiv = aufklapp_merker(n,"checken");
  if ( aktiv == "ja" ) {
    document.getElementById(klappreihe[n]).style.display = "none";
  } else {
    for (var i = 1; i <= klappreihe.length - 1; i++) {
      if ( i != n ) {
        document.getElementById(klappreihe[i]).style.display = "none";
      } else {
        document.getElementById(klappreihe[i]).style.display = "block";
        aufklapp_merker(klappreihe[i],"merken");
      }
    }
  }
}
//--></script>

<a href="#" onclick="aufklappen('1');return false">Klicken</a>
<a href="#" onclick="aufklappen('2');return false">Klicken</a>
<a href="#" onclick="aufklappen('3');return false">Klicken</a>
<a href="#" onclick="aufklappen('4');return false">Klicken</a>

Um die erste Funktion ganz oben geht's mir wie gesagt nicht, ausser jemand weiss, wie man den "status" an onClick übergeben kann.
Für Hilfe zum zweiten Code wäre ich sehr dankbar!

Anschauen kann man sich's hier.

Vielen Dank für Eure Hilfe,

Konfusion

  1. Hallo,

    du kannst dich doch mit this bzw. this.id auf das den event auslösende element beziehen, würde ich sagen. zudem kannst du eine globale variable mit jederzeit ändern. mein tipp immer: ganz kleine testreihe, schritt für schritt.

    1. krieg die id zu packen
    2. krieg die globale var bestückt

      
    <script type="text/javascript">  
    //<![CDATA[  
    myGlobal = "nochNix";  
    showId = function(element) {  
    	alert(element.id);  
    	myGlobal = element.id;  
    }  
    showGlobalVar = function() {  
    	alert(myGlobal);  
    }  
    //]]>  
    </script>  
    
    
      
    <button onclick="showId(this)" id="id1">showId (id1)</button>  
    <button onclick="showId(this)" id="id2">showId (id2)</button>  
    <button onclick="showGlobalVar()">showGlobalVar</button>  
    window.onload = function () {  
     document.getElementsName  
    }  
    
    

    Also, man muss "this" übergeben.

    Gruß

    jobo

    1. Hi there,

      du kannst dich doch mit this bzw. this.id auf das den event auslösende element beziehen, würde ich sagen. zudem kannst du eine globale variable mit jederzeit ändern. mein tipp immer: ganz kleine testreihe, schritt für schritt.

      Globale Variablen sind immer eine schlechte "Lösung". Es ist immer besser, einem Objekt eine bestimmte Eigenschaft zuzuweisen...

      1. Hallo,

        Globale Variablen sind immer eine schlechte "Lösung". Es ist immer besser, einem Objekt eine bestimmte Eigenschaft zuzuweisen...

        Aber wie soll das hier aussehen? Extra ein Objekt myGlobalObject.myStatus? Ist das nicht Jacke wie Hose? Ein Objekt ist doch auch "nur" eine (globale) Variable, bzw. ein Namensraum für selbige. Frage, ob das in einem sehr kleinen Rahmen Sinn macht.

        Gruß

        jobo

        1. Hi,

          Globale Variablen sind immer eine schlechte "Lösung". Es ist immer besser, einem Objekt eine bestimmte Eigenschaft zuzuweisen...

          Aber wie soll das hier aussehen? Extra ein Objekt myGlobalObject.myStatus?

          Wenn du OO programmierst, dann wird auch die Funktion, die beim Eintreten des Events ausgeführt werden soll, schon nicht im globalen Raum hängen, sondern Methode eines Objektes sein.
          An diese Objektinstanz kann man dann auch die Werte binden, von denen die Funktion "wissen" muss, wie bspw. von dem Element, welches zuvor behandelt wurde.

          MfG ChrisB

          --
          Light travels faster than sound - that's why most people appear bright until you hear them speak.
          1. Hi,

            ich blick bei Eurer Diskussion leider nicht durch.

            Ich habe jetzt folgendes programmiert:

            var status = new Array("empty,nochNix,nochNix,nochNix,nochNix");  
              
            function showClass(klasse,x) {  
              for (var i = 1; i <= status.length -1; i++) {  
                status[i] = klasse;  
              }  
            }  
              
            function aufklappen(n) {	  
              var klappreihe = new Array("empty","aufklapptext1","aufklapptext2","aufklapptext3","aufklapptext4");  
              for (var i = 1; i <= klappreihe.length - 1; i++) {  
                if ( i != n || status[i] == "on" ) {  
                  document.getElementById(klappreihe[i]).style.display = "none";  
                  document.getElementById(klappreihe[i]).class = "off";  
                } else {  
                  document.getElementById(klappreihe[i]).style.display = "block";  
                  document.getElementById(klappreihe[i]).class = "on";  
                }  
              }  
            }
            
            <a class="off" href="#" onclick="showClass(this.className,'1');aufklappen('1')">Klicken</a>  
            <a class="off" href="#" onclick="showClass(this.className,'2');aufklappen('2')">Klicken</a>  
            <a class="off" href="#" onclick="showClass(this.className,'3');aufklappen('3')">Klicken</a>  
            <a class="off" href="#" onclick="showClass(this.className,'4');aufklappen('4')">Klicken</a>
            

            Warum erkennt mein Javascript nicht, dass der bereits aufgeklappte Auslöser die Klasse "on" hat?

            Für noch etwas konkrete Hilfe wäre ich da sehr dankbar.

            Danke, Konfusion

            1. Hallo,

              Weia, deinen Nick hast du treffend gewählt ;-))

              Ich habe jetzt folgendes programmiert:

              Das ist alles ziemlicher Stuss.

              var status = new Array("empty,nochNix,nochNix,nochNix,nochNix");

              Soll das ein http://de.selfhtml.org/javascript/objekte/array.htm@title=Array mit 5 Werten werden? So geht das aber nicht. Es wird ein Array mit nur einem Wert, einem String.

              Was genau willst du denn ereichen? Jedes DIV soll beim Anklicken abwechselnd erscheinen und verschwinden, richtig?

              Wenn ja, brauchst du eine Funktion, die das leistet, etwas wie:

              element.style.display = element.style.display === 'none' ? 'block' : 'none';  
              
              

              Außerdem soll immer nur maximal ein DIV sichtbar sein, richtig?
              Falls ja, brauchst du eine Funktion, die beim Einblenden eines DIV alle anderen unsichtbar macht. etwa so:

                
                if(element.style.display !== 'none') {  
                  for(var i=0; divs[i]; i++) {divs[i].style.display = 'none';}  
                }
              

              Das macht alle unsichtbar, danach dann das gewünschte sichtbar machen mit erstgenannter Funktion. Ein Array divs musst du natürlich zur Verfügung stellen.

              Allerdings wird es schwierig bis unmöglich, ein mit display='none' verstecktes DIV nochmal anzuklicken, denn es ist ja dann weg ;-)

              Gruß, Don P

              1. Hi

                Was genau willst du denn ereichen? Jedes DIV soll beim Anklicken abwechselnd erscheinen und verschwinden, richtig?

                richtig!

                Außerdem soll immer nur maximal ein DIV sichtbar sein, richtig?

                auch richtig!

                Allerdings wird es schwierig bis unmöglich, ein mit display='none' verstecktes DIV nochmal anzuklicken, denn es ist ja dann weg ;-)

                Es wird nicht das ausgeblendete DIV angeklickt, sondern ein Link, der immer sichtbar ist. Insofern stellt das kein Problem dar.

                Vielen Dank, damit kann ich weiter arbeiten.
                Im Moment habe ich was anderes zu tun, aber ich melde mich, wenn ich Ergebnisse habe ;-)

                Danke, Konfusion

              2. Hi,

                var status = new Array("empty,nochNix,nochNix,nochNix,nochNix");

                Soll das ein http://de.selfhtml.org/javascript/objekte/array.htm@title=Array mit 5 Werten werden? So geht das aber nicht. Es wird ein Array mit nur einem Wert, einem String.

                Hoppla, Flüchtigkeitsfehler.

                element.style.display = element.style.display === 'none' ? 'block' : 'none';

                  
                Was macht denn das eigentlich? Gibt's 3===?  
                Diese eine Zeile wechselt das mittels `'none' ? 'block' : 'none';`{:.language-javascript} hin und her? Spannend.  
                  
                
                > ~~~javascript
                  
                
                >   if(element.style.display !== 'none') {  
                >     for(var i=0; divs[i]; i++) {divs[i].style.display = 'none';}  
                >   }
                
                

                Das macht alle unsichtbar, danach dann das gewünschte sichtbar machen mit erstgenannter Funktion. Ein Array divs musst du natürlich zur Verfügung stellen.

                Echt toll. Danke, ich werde das heute nachmittag ausprobieren

                1. Hi,

                  Was macht denn das eigentlich? Gibt's 3===?

                  http://de.selfhtml.org/javascript/sprache/operatoren.htm#vergleich

                  Diese eine Zeile wechselt das mittels 'none' ? 'block' : 'none'; hin und her? Spannend.

                  http://de.selfhtml.org/javascript/sprache/bedingt.htm#entweder_oder

                  MfG ChrisB

                  --
                  Light travels faster than sound - that's why most people appear bright until you hear them speak.
                  1. Hi,

                    http://de.selfhtml.org/javascript/sprache/operatoren.htm#vergleich

                    Wird der Bergleichsoperator === auch von IE 6 interpretiert? Den muss man ja leider immer noch mitnehmen.

                    http://de.selfhtml.org/javascript/sprache/bedingt.htm#entweder_oder

                    Switch-Anweisung: toll!

                    Danke ;-)

                    1. Hallo,

                      Wird der Vergleichsoperator === auch von IE 6 interpretiert? Den muss man ja leider immer noch mitnehmen.

                      Ja, wird er. Man *muss* ihn hier nicht unbedingt benutzen, aber ich habe mir das so angewöhnt, wenn eh klar ist, dass Typgleichheit vorliegt. Könnte sein, dass es so etwas schneller geht, weil sonst ggf. eine automatische Typumwandlung stattfindet müsste, bevor der Vergleich zu einem Ergebnis führt, was hier auf jeden Fall unnötig ist.

                      Uralte Browser, die das nicht unterstützen, sind heutzutage wohl nicht mehr unterwegs.

                      Gruß, Don P

                      1. Hallo Don,

                        Wird der Vergleichsoperator === auch von IE 6 interpretiert? Den muss man ja leider immer noch mitnehmen.

                        Uralte Browser, die das nicht unterstützen, sind heutzutage wohl nicht mehr unterwegs.

                        es soll eine noch nicht ausgestorbene Gattung des homo developens reticuli [1] geben, die sich Webseiten in Netscape 3 bis 4 sowie IE 2 bis 4 ansieht. Weitestgehend stimmt der Personenkreis mit den Leuten überein, die sich um Darstellungs- und Javascriptfehler in Standalone-IEs und vergleichbaren Helfern sorgen, die in realen Browsern nicht auftreten :-)

                        Lästernde Grüße

                        Vinzenz

                        [1] Fachkreise bezweifeln die Zugehörigkeit dieser Gattung zu homo sapiens.

                        1. [latex]Mae  govannen![/latex]

                          Uralte Browser, die das nicht unterstützen, sind heutzutage wohl nicht mehr unterwegs.

                          es soll eine noch nicht ausgestorbene Gattung des homo developens reticuli [1] [...]

                          reticuli? ridiculi! :)

                          Cü,

                          Kai

                          --
                          A workaround for an avoidable problem often adds clutter and overhead to the program which
                          could have been avoided by not creating the problem in the first place.(Garrett Smith/clj)
                          Foren-Stylesheet Site Selfzeug JS-Lookup
                          SelfCode: sh:( fo:| ch:? rl:( br:< n4:( ie:{ mo:| va:) js:| de:> zu:) fl:( ss:| ls:?
                        2. es soll eine noch nicht ausgestorbene Gattung des homo developens reticuli [1] geben, die sich Webseiten in Netscape 3 bis 4 sowie IE 2 bis 4 ansieht. Weitestgehend stimmt der Personenkreis mit den Leuten überein, die sich um Darstellungs- und Javascriptfehler in Standalone-IEs und vergleichbaren Helfern sorgen, die in realen Browsern nicht auftreten :-)

                          Es ist seit langen schon nicht mehr möglich mit Netscape 3 oder dem IE 4 im Internet zu surfen.

                          Netscape 3 hat das Problem, das er jeden JS Fehler mit einem Pop quittiert (kann man abschalten) und CSS Quellcode anzeigt wenn er nicht auskommentiert ist, zudem litt er unter massiver Absturzhäufigkeit (was aber auch an Win95 gelegen haben könnte).

                          Der IE 4 zeigt auch JS Fehler mit einem Popup an, aber stürzt darüber hinaus verdammt schnell bei akutellem CSS ab. Genau das gleiche gilt für Netscape 4.

                          Es kann also eigentlich niemanden mehr geben der sich das Internet mit diesen Browsern "ansieht", da nach wenigen Seiten der Browser abgestürzt ist. die die in den Logs auftauchen, sind wohl eher lustige Menschen die Webmaster verunsichern wollen.

                          Also dürfte dem === Operator nichts im Wege stehen

                          Struppi.

        2. Hi there,

          Aber wie soll das hier aussehen? Extra ein Objekt myGlobalObject.myStatus? Ist das nicht Jacke wie Hose? Ein Objekt ist doch auch "nur" eine (globale) Variable, bzw. ein Namensraum für selbige. Frage, ob das in einem sehr kleinen Rahmen Sinn macht.

          Das macht deshalb Sinn, weil das Objekt ja in den meisten Fällen schon existiert (auch wenn es aus Unkenntnis oder anderen Gründen vielleicht nicht als solches erkannt oder angesprochen wird) - so auch im vorliegenden Fall, wo das Objekt eben der entsprechende ein- und auszublendende Bereich ist. (Wobei, wie ich schon geschrieben habe, hier eine zusätzliche Status-Eigenschaft komplett überflüssig ist - das Objekt hat ja schon eine visibility- oder display-Eigenschaft.)

  2. Hi there,

    Schaut Euch das mal an bitte. Könnt Ihr mir da helfen? So schwer kann das eigentlich nicht sein. Ich habe zuerst versucht, eine Variable "status" an den Event-Handler onClick zurückzugeben - funktioniert aber leider nicht:

    viel zu kompliziert. Frag einfach ab, ob das entsprechende Element sichtbar ist oder nicht und reagiere entsprechend...