minestarm: Objekt per Mausklick anzeigen und schließen

Hallo,

Bin gerade dabei eine "Wordpress-Seite" aufzubauen, aber dass sei erstmal dahingestellt den hier geht es um den Header der rein aus HTML/CSS und Java bestehen soll.

Meine Webseite soll bzw. hat eine Desktop-Version als auch eine Mobile-Version die bei Bildschirmgröße/Fenstergröße:985px umschaltet. Funktioniert alles wunderbar...

In der Desktop-Version wird die Suche im Banner angezeigt und die Navigation ist geöffnet unter dem Banner
In der Mobile-Version ist die Suche und die Navigation versteckt und wird über einen Button (Div-Tag) geöffnet.

Hier erstmal der Link zu meiner Seite: "http://minestarm.lima-city.de/"

Jetzt geht es erstmal nur um die Mobile-Version, denn ich möchte sobald man den "Menü-Button" anklickt, dass sich das Menü öffnet und die Suche schließt falls geöffnet. Andersherum sobald man den "Suchen-Button" anklickt möchte ich dass sich die Suche öffnet und die Navigation schließt falls geöffnet. Klickt man ein weiteres Mal auf den jeweiligen Button schließt sich das zuvor geöffnete Objekt (Suche/Navigation). Zusätzlich sollen sich noch die CSS-Eigenschaften der Button ändern wenn das jeweilige Objekt (Suche/Navigation) geöffnet ist.

Aktuell habe ich nur geschafft, dass sich per Klick das Objekt öffnet und per weiterer Klick wieder schließt.

Das hier sind die "Button´s ("menue" und "sfm" ... "navi" ist die ID für die Navigation und "sboxm" ist die Suche)
HTML:

<div id = "menuesearch">  
    <div id = "menue" onclick="toggle_visibility('navi');">  
    </div>  
    <div id = "sfm" onclick="toggle_visibility('sboxm'); nomenue();">  
    </div>  
</div>

Das ist mein bisheriges Script (ehrlich gesagt auch nur aus dem Inet zusammengebastelt)
HTML:

<script type="text/javascript">  
    function toggle_visibility(id) {  
           var e = document.getElementById(id);  
           if(e.style.display == 'block')  
              e.style.display = 'none';  
           else  
          e.style.display = 'block';  
    }  
</script>  

Bin leider mit Java-Script nur wenig bis gar nicht vertraut. Das wäre auch mit das einzigste Java was ich auf meiner Seite brauche. HTML und CSS bin ich doch schon sehr viel mehr erfahren. Würde mich sehr freuen wenn mir jemand helfen könnte. Den Code hab ich vereinfacht damit unwichtige Elemente nicht für Verwirrung sorgen... Falls ich was vergessen habe bitte Bescheid sagen.

MfG minestarm

  1. Hallo,

    <div id = "menuesearch">

    <div id = "menue" onclick="toggle_visibility('navi');">
        </div>
        <div id = "sfm" onclick="toggle_visibility('sboxm'); nomenue();">
        </div>
    </div>

      
    Das ist schon ganz richtig gedacht (die Umsetzung von nomenu scheint dir noch zu fehlen).  
      
    Deine Anforderungen vollständig umgesetzt, soweit ich sie verstanden habe:  
      
    `<div id="menue-button"  onclick="[code lang=javascript]toggle('menue'); hide('search');`{:.language-html}">…</div>  
    <div id="search-button" onclick="`toggle('search'); hide('menue');`{:.language-javascript}">…</div>[/code]  
      
    Die Bezeichner habe ich kurzerhand geändert, es geht bloß darum, was beim Klick alles passieren muss.  
      
    Die toggle-Funktion hast du schon (toggle\_visibility), also fehlt nur die hide-Funktion.  
      
    
    > Das ist mein bisheriges Script (ehrlich gesagt auch nur aus dem Inet zusammengebastelt)  
      
    Wenn du in die Funktion toggle\_visibility schaust, siehst du, wie das Verstecken geht.  
      
    
    >     function toggle\_visibility(id) {  
    >            var e = document.getElementById(id);  
      
    Holt das Element mit der angegebenen ID.  
      
    
    >            if(e.style.display == 'block')  
      
    Prüft, ob der CSS-Inline-Style »display« den Wert »block« hat. Siehe <http://de.selfhtml.org/css/eigenschaften/positionierung.htm#position@title=display in SELFHTML>.  
      
    »block« steht hier für sichtbar (kennst du aus CSS wahrscheinlich).  
      
    
    >               e.style.display = 'none';  
      
    Falls das Element sichtbar ist, verstecke es. Ändere den display-Wert auf none.  
      
    
    >            else  
    >           e.style.display = 'block';  
      
    Andernfalls zeige das Element an. Ändere den display-Wert auf block.  
      
    Jetzt sollte klar werden, wie du ein Element verstecken kannst und wie eine hide-Funktion aussehen kann:  
      
    ~~~javascript
    function hide(id) {  
      var e = document.getElementById(id);  
      e.style.display = 'none';  
    }
    

    Dann lässt sich hide('menue') bzw. hide('search') aufrufen. Für »menu« und »search« sind natürlich deine IDs einzusetzen.

    Disclaimer: Das ist äußerst vereinfacht. Es gibt andere, letztlich bessere Methoden, um die Sichtbarkeit eines Elements zu ändern, z.B. das Hinzufügen/Entfernen einer Klasse mit entsprechenden Formatierungen im Stylesheet. Die erfordern aber mehr als ein paar Zeilen JavaScript.

    Mathias

    1. OK vielen Dank dass hat super geklappt! Jetzt habe ich für eine einzelne Webseite fast genau die gleiche Anwendung, nur mehrere Div-Tags die geschlossen werden sollen wenn sich eins öffnet...

      Hier mein aktueller CODE:

      <html>  
      <head>  
      <style type="text/css">  
      #question1,  
      #question2,  
      #question3,  
      #question4,  
      #question5,  
      #question6 {  
      	background-color: gray;  
      	border: 1px solid black;  
      	width:100%;  
      	height: 50px;  
      }  
      #answer1,  
      #answer2,  
      #answer3,  
      #answer4,  
      #answer5,  
      #answer6 {  
      	background-color: lightgray;  
      	border: 1px solid black;  
      	border-top: none;  
      	width:100%;  
      	height: 50px;  
      	display: none;  
      }  
      </style>  
      <script type="text/javascript">  
      	function toggle(id) {  
      		   var e = document.getElementById(id);  
      		   if(e.style.display == 'block')  
      			  e.style.display = 'none';  
      		   else  
      		  e.style.display = 'block';  
      }  
      </script>  
      <script type="text/javascript">  
      	function hide(id) {  
      	  var e = document.getElementById(id);  
      	  e.style.display = 'none';  
      }  
      </script>  
      </head>  
        
      <body>  
      <div id="tabmenue">  
      	<div id="question1" onclick="toggle('answer1'); hide('answer2,answer3')">Frage1  
      	</div>  
      	<div id="answer1">Antwort1  
      	</div>  
      	<div id="question2" onclick="toggle('answer2'); hide('answer1')">Frage2  
      	</div>  
      	<div id="answer2">Antwort2  
      	</div>  
      	<div id="question3" onclick="toggle('answer3'); hide('answer1')">Frage3  
      	</div>  
      	<div id="answer3">Antwort3  
      	</div>  
      	<div id="question4" onclick="toggle('answer4'); hide('answer1')">Frage4  
      	</div>  
      	<div id="answer4">Antwort4  
      	</div>  
      	<div id="question5" onclick="toggle('answer5'); hide('answer1')">Frage5  
      	</div>  
      	<div id="answer5">Antwort5  
      	</div>  
      	<div id="question6" onclick="toggle('answer6'); hide('answer1')">Frage6  
      	</div>  
      	<div id="answer6">Antwort6  
      	</div>  
      </div>  
      </body>  
      </html>
      

      Wenn ich auf question1 klicke sollen alle answer´s geschlossen werden aber answer1 geöffnet werden und auf question2 sollen alle answer´s geschlossen werden aber answer 2 geöffnet werden und so weiter ? Bin da schon wieder ewig lang am rumprobieren und am rumsuchen hab da aber nix gefunden bisher.

      Wäre super wenn auch da mir jemand helfen kann.

      MfG minestarm

      1. Mahlzeit,

        Wäre super wenn auch da mir jemand helfen kann.

        Du nimmst statt der ID eine Klasse und manipulierst die Klasseneigenschaft, nicht die Eigenschaft des Elementes direkt.

        --
        42
      2. Hallo,

        #question1,
        #question2,
        #question3,
        #question4,
        #question5,
        #question6 {
        background-color: gray;
        border: 1px solid black;
        width:100%;
        height: 50px;
        }

        Verwende besser zwei Klassen question und answer, anstatt dutzende IDs mit Nummern. Dann reicht .question {} .answer {}.

        <div id="question1" onclick="toggle('answer1'); hide('answer2,answer3')">Frage1
        </div>

        Die hide-Funktion erwartet *eine* ID und holt sich das zugehörige Element, daher lassen sich nicht einfach mehrere IDs durch Komma getrennt übergeben.

        Natürlich könnte eine hide-Funktion mehrere IDs entgegen nehmen und sämtliche Parameter durchlaufen:

        var hide = function() {  
          // Durchlaufe alle Parameter (arguments-Liste) mit einer for-Schleife  
          for (var i = 0, l = arguments.length; i < l; i++) {  
            document.getElementById(arguments[i]).style.display = 'none';  
          }  
        };  
          
        // Benutzung:  
        hide('id1', 'id2', 'id3', 'id3',);
        

        Aber wenn es dutzende Fragen/Antworten gibt, dann ist es nicht mehr praktisch, überall einzelne IDs aufzulisten. Wenn du zehn Fragen hast, müsstest du jeweils neun IDs zum Verstecken auflisten. Solche Wiederholungen sind unschön und lassen sich vermeiden.

        Im vorigen Posting hatte ich beweusst eine vereinfachte Lösung gezeigt und hatte angemerkt, dass sich das verbessern ließe. Da du jetzt eine komplexere Logik brauchst, würde ich eine allgemeine Lösung vorschlagen:

        http://codepen.io/molily/pen/eCsDt

        Das ist natürlich komplizierter, aber so ungefähr sähe eine bessere, wartbare Lösung aus.

        Auf IDs wird hier komplett verzichtet, damit ist die Anzahl der Fragen/Antworten variabel. Ein Pärchen wird jeweils mit gruppiert und bekommt die Klasse »qa«:

        <section class="qa">  
            <h2 class="question">Frage</h2>  
            <p class="answer">Antwort</p>  
        </section>
        

        Das Zeigen und Verstecken wird nicht mehr durch das Umschalten von display gelöst, sondern durch das Hinzufügen und Entfernen der Klasse »inactive«. Das ist mit dem classList-Objekt möglich, das das Hinzufügen (add), Löschen (remove), Umschalten (toggle) und Abfragen (contain) einer Klasse erlaubt.

        Im CSS steht dann der Code, der die Antwort ausblendet. Dieses Ausblenden erfolgt in einer Weise, dass der Text zugänglich für Screenreader bleibt. display: none würde den Text nämlich komplett verstecken.

        Wenn JavaScript nicht aktiviert ist, dann sind die Antworten sofort sichtbar, d.h. sie werden erst mit JavaScript durch das Hinzufügen der »invisible«-Klasse versteckt.

        Noch mal Hintergrundinfos zum Event-Handling:

        http://molily.de/js/event-handling-grundlagen.html
        http://molily.de/js/event-handling-fortgeschritten.html
        http://molily.de/js/event-handling-onload.html

        Mathias

        1. OK vielen Dank für den Code, funktioniert fast wunderbar ... komplett in eine HTML reingepackt und hochgeladen klappts,

          aber da ich eine "Wordpress-Seite" habe ist das mit dem Code einbinden nicht so leicht, habs schließlich doch hinbekommen aber per Mausklick öffnen sich nicht die Antworten.

          Die Antworten werden nicht angezeigt (lediglich die Fragen) daher müsste ja normalerweise das Javascript richtig eingebunden sein aber wie gesagt bei einem Mausklick passiert garnichts.

          Hast du oder jemand Ahnung ob Wordpress irgendwas an diesem Javascript nicht mag:

          <style type="text/css">  
          body {  
              font-family: sans-serif;  
          }  
            
          /*  
          Verstecke auf zugängliche Weise  
          Siehe http://snook.ca/archives/html_and_css/hiding-content-for-accessibility  
          */  
          .inactive .answer {  
          	position: absolute !important;  
          	height: 1px; width: 1px;  
          	overflow: hidden;  
          	clip: rect(1px 1px 1px 1px); /* IE6, IE7 */  
          	clip: rect(1px, 1px, 1px, 1px);  
          }  
            
          .answer {  
          	background-color: gray;  
          	border: 1px solid black;  
          }  
            
          .js .question {  
              cursor: pointer;  
          	background-color: lightgray;  
          	border: 1px solid black;  
          }  
          </style>  
          <script type="text/javascript">  
          // Füge js-Klasse zum html-Element hinzu, damit wir Styles angeben können,  
          // die nur greifen, wenn JavaScript aktiviert ist.  
          document.documentElement.classList.add('js');  
            
          // Führe eine Funktion beim erfolgreichen Laden der Seite aus  
          document.addEventListener('DOMContentLoaded', function() {  
            'use strict';  
            
            // Konfiguration: Klassennamen  
            var questionClass = 'question';  
            var inactiveClass = 'inactive';  
            
            // Speichert das aktive qa-Element  
            var active;  
            
            // Schaltet die Sichtbarkeit eines qa-Elements um  
            var toggle = function(element) {  
              // Verstecke das aktive qa-Element  
              if (active && active != element) {  
                  active.classList.add(inactiveClass);  
              }  
              // Toggle das angeklickte  
              element.classList.toggle(inactiveClass);  
              // Speichere das aktive in einer Variablen,  
              // damit wir es später verstecken können  
              active = element;  
            };  
            
            // Event-Handler für alle Klicks innerhalb der FAQ  
            var faqClick = function(event) {  
              // Greife auf das Ereignis-Zielelement zu und prüfe,  
              // ob es eine Frage ist (hat es die Klasse »question«?).  
              if (event.target.classList.contains(questionClass)) {  
                // Gehe zum Elternelement (dem qa-Element)  
                var element = event.target.parentNode;  
                // Schalte um  
                toggle(element);  
              }  
            };  
            // Registriere den click-Event-Handler beim gemeinsamen faq-Element.  
            // Hier kommen durch das Aufsteigen von Events alle Klick-Ereignisse an,  
            // daher können wir sie zentral überwachen, anstatt bei jedem question-Element einzeln  
            document.getElementById('faq').addEventListener('click', faqClick);  
            
            // Füge beim Laden der Seite allen qa-Elementen die Klasse »inactive« hinzu,  
            // um anfangs alle Antworten auszublenden.  
            var qas = document.querySelectorAll('.qa');  
            for (var i = 0, l = qas.length; i < l; i++) {  
              qas[i].classList.add(inactiveClass);  
            }  
          });  
          </script>  
            
          <div id="faq">  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          <section class="qa">  
              <h2 class="question">Frage</h2>  
              <p class="answer">Antwort</p>  
          </section>  
          </div>
          

          Bin langsam am verzweifeln diesen Code da ins Wordpress hineinzubekommen. Hier der Link zur Seite um die es geht: http://minestarm.lima-city.de/?page_id=410

          MfG minestarm