Reaper: Div container gegen anderen Tauschen

Hallo zusammen.

Ich versuche gerade 2 Container gegeneinander zu tauschen bei konpfdruck, hier mal das wichtigste aus dem code:

  
  
<script type="text/javascript">  
<!--  
function change(){  
d1=document.getElementById('Theme');  
d2=document.getElementById('Themewide');  
d2.style.display='none';  
onclick("d1.style.display='none';d2.style.display='block';")  
}  
//-->  
</script>  
  
<div id="style-chooser">  
<a href="#" onclick="change();return false">Test</a>  
  
  
    	<div id=Theme>*/ ... Mehrere Links ...*/  
        </div>  
        <div id="Themewide">*/ ... weitere Links ... */  
        </div>  
    </div>  

Das ganze sollte eigentlich folgendes Leisten:
Bei Seitenaufruf soll der 2. Container (Themewide) nicht angezeigt werden und nur der erste (Theme).
Bei Click auf "Test" soll der 2. Container eingeblendet werden und der 1. Container ausgeblendet werden.
Bei erneutem Click auf Test soll der 2. Container wieder ausgeblendet und der 1. Container eingeblendet werden. und so weiter.
Am besten natürlich mit einem Fade-Effekt, aber das ist ja erstmal nebensache ^^

Ich habe mich mal mehr oder weniger ohne Ahnung selber dran versucht, leider war das ergebniss nicht erfolgreich. Ich bräuchte eine funktion, die bei Click jeweils den Style auf none bzw auf block setzt (je nachdem worauf der vorher steht).

Ich hoffe mir kann da jemand helfen :)

MFG

Reaper

  1. Hallo,

    <script type="text/javascript">
    <!--

    Du brauchst Scripte nicht mehr in <!-- … //--> einbetten, sofern du nicht Browser von 1995 unterstützen willst (kein Witz, alle neueren Browser brauchen das nicht).

    function change(){
    d1=document.getElementById('Theme');
    d2=document.getElementById('Themewide');
    d2.style.display='none';
    onclick("d1.style.display='none';d2.style.display='block';")

    Was beabsichtigt diese Schreibweise mit onclick("…")? Das wird wahrscheinlich einen Fehler geben. Es gibt keine globale onclick-Funktion (sofern du keinen Event-Handler für window.onclick registriert hast). Wenn du den Code direkt ausführen möchtest, schreib ihn direkt hin.

    d1.style.display = 'none';  
    d2.style.display = 'block';
    

    Falls du stattdessen irgendwo Event-Handler registrieren willst (onclick legt das nahe), dann schau dir einmal folgendes Tutorial an:

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

    Bei Seitenaufruf soll der 2. Container (Themewide) nicht angezeigt werden und nur der erste (Theme).

    Okay, das ist eine Frage von entsprechenden CSS-Regeln.

    Bei Click auf "Test" soll der 2. Container eingeblendet werden und der 1. Container ausgeblendet werden.

    Da geht dein Ansatz mit element.style.display = 'block' bzw. 'none' schon in die richtige Richtung.

    Es gibt noch andere Methoden, die weniger JavaScript erfordern, nämlich das Umschalten einer Klasse mit JavaScript. Das Zeigen und Verstecken der Element wird dann über CSS-Regeln umgesetzt, die greifen, wenn die Klasse gesetzt ist oder nicht. Das wurde u.a. in diesem Thread diskutiert: http://forum.de.selfhtml.org/archiv/2014/1/t216394/

    Bei erneutem Click auf Test soll der 2. Container wieder ausgeblendet und der 1. Container eingeblendet werden. und so weiter.

    Dazu kannst du eine <http://de.selfhtml.org/javascript/sprache/bedingt.htm@title=Fallunterscheidung mit if> schreiben, die die aktuelle Sichtbarkeit abfragt und entsprechend die Element ein- und ausblendet. Logik:

    Wenn Element 1 sichtbar ist
      Verstecke Element 1
      Zeige Element 2
    andernfalls
      Zeige Element 1
      Verstecke Element 2

    Am besten natürlich mit einem Fade-Effekt, aber das ist ja erstmal nebensache ^^

    Das lässt sich am einfachsten mit einer CSS-Transition auf die opacity-Eigenschaft lösen.

    Grüße
    Mathias

    1. Hi

      Danke schonmal für die schnelle Hilfe :)

      Ich bin in JavaScript leider völlig neu ^^
      Die IF-Methode finde ich am logischsten hab aber nicht ganz verstanden, wie das dann zu notieren ist.
      Ich habs deswegen erstmal mit dem Umschalten der Klasse versucht:

        
      <script type="text/javascript">  
      function change(){  
        document.documentElement.className = document.documentElement.className === "Theme" ? "ThemeDis" : "Theme";  
      }  
      {  
        document.documentElement.className = document.documentElement.className === "Themewide" ? "ThemewideDis" : "Themewide";  
      }  
      </script>  
      <style>  
              #Theme {  
      		display:block;  
      	}  
      	#ThemeDis {  
      		display:none;  
      	}  
      	#Themewide {  
      		display:none;  
      	}  
      	#ThemewideDis {  
      		display:block;  
      	}  
      </style>  
      <div id="style-chooser">  
      <a href="#" onclick="change();return false">Test</a>  
        
        
                  <div id=Theme>*/ ... Mehrere Links ...*/  
              </div>  
              <div id="Themewide">*/ ... weitere Links ... */  
              </div>  
          </div>  
      
      

      Die Ausgangssituation stimmt jetzt natürlich, das ändern funktioniert leider noch immer nicht :S

      Zum übergang habe ich mich mal in den Link von die eingelesen
      Ich müsste da mit
      transition: opacity 1s
      arbeiten, hab aber nicht ganz verstanden, wie ich dann zuordne, dass das beim ein, bzw ausblenden benutzt werden soll.

      Ich hoffe du kannst mir da helfen :)

      MFG

      Reaper

      1. Hi,

        Die Ausgangssituation stimmt jetzt natürlich, das ändern funktioniert leider noch immer nicht :S

        Du änderst zwar die Klasse des html-Elements – hast aber keinerlei Regeln in deinem Stylesheet für diese Klassen.

        MfG ChrisB

        --
        Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
        1. Öhhm

            
          #Theme {  
          	display:block;  
          }  
          #ThemeDis {  
          	display:none;  
          }  
          #Themewide {  
          	display:none;  
          }  
          #ThemewideDis {  
          	display:block;  
          }
          

          Hab das doch so geschrieben:

          Das eine soll von #Theme zu #ThemeDis geändert werden, dann ändert sich display:block zu display:none sollte also nicht mehr angezeigt werden.
          Das andere ändert sich von #Themewide zu #ThemewideDIS also von display:none zu display:block sollte dann also angezeigt werden.
          Oder mache ich da was falsch?, wenn ich manuell die klassen tausche funktioniert das :/

          MFG

          1. Hallo Reaper,

            deinen Elementen fehlt die Klasse. Und wessen Klasse willst du mit

            document.documentElement.className

            ansprechen? Ich hätte hier document.getElementById genommen.

            Gruß, Jürgen

            1. Ich hab halt leider noch nicht so viel Ahnung von Javascript.
              Wie müsste das denn richtig aussehen ?

          2. Hi,

            Öhhm

            #Theme {
            display:block;
            }
            #ThemeDis {
            display:none;
            }
            #Themewide {
            display:none;
            }
            #ThemewideDis {
            display:block;
            }

            
            >   
            > Hab das doch so geschrieben  
              
            Diese Regeln haben keinerlei Bezug zu irgendwelchen \*Klassen\*.  
              
            Erst mal ab zur [Grundlagen-Nachhilfe](http://wiki.selfhtml.org/wiki/CSS/Selektoren).  
              
            MfG ChrisB  
              
            
            -- 
            Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
            
      2. Hallo,

        Ich bin in JavaScript leider völlig neu ^^

        Dann arbeite bitte ein JavaScript-Tutorial eigenständig durch. Leute hier können dir fertigen Code schreiben und du kannst fremden Code kopieren, aber verstehen musst du ihn letztlich selbst.

        Die IF-Methode finde ich am logischsten hab aber nicht ganz verstanden, wie das dann zu notieren ist.
        Ich habs deswegen erstmal mit dem Umschalten der Klasse versucht:

        <script type="text/javascript">
        function change(){
          document.documentElement.className = document.documentElement.className === "Theme" ? "ThemeDis" : "Theme";
        }
        {
          document.documentElement.className = document.documentElement.className === "Themewide" ? "ThemewideDis" : "Themewide";
        }

        Dieser Code ist syntaktisch fehlerhaft. Bitte lies dir einmal [ref:self812;javascript/sprache/bedingt.htm@title=Bedingte Anweisungen (if-else)] durch.

        Ich schlage vor, mir einer einfachen if-else-Anweisung zu arbeiten:

        [code lang=javascript]if (…) {
          …
        } else {
          …
        }

          
        In deinem Code wird eine <http://de.selfhtml.org/javascript/sprache/bedingt.htm#entweder_oder@title=Kurzform> verwendet. Das geht ebenfalls, hat denselben Effekt, ist aber etwas kryptisch, schwer zu lesen und zu verstehen.  
          
        
        >         #Theme {  
        > 		display:block;  
        > 	}  
        > 	#ThemeDis {  
        > 		display:none;  
        > 	}  
        > 	#Themewide {  
        > 		display:none;  
        > 	}  
        > 	#ThemewideDis {  
        > 		display:block;  
        > 	}  
          
        Anscheinend hat du die Logik des Umschaltens der Klasse noch nicht ganz verstanden. Die Idee hinter dem Umschalten der Klasse ist, dass man bei einem Elternelement eine Klasse ändert und dann eine Formatierungsregel aktiv wird, die das Nachfahrenelement betrifft. Siehe auch das [ursprüngliche Beispiel](http://forum.de.selfhtml.org/archiv/2014/1/t216394/#m1483795) von Gunnar, aus dem der Code stammt.  
          
        Einfaches Beispiel:  
          
        ~~~html
        <div id="elternelement">  
         <div id="eins">…</div>  
         <div id="zwei">…</div>  
        </div>  
        
        

        Standardmäßig ist #eins sichtbar und #zwei nicht:

        #eins { display: block; } /* Standardeinstellung, ich hab’s einmal ausdrücklich aufgeführt */  
        #zwei { display: none; }
        

        Wenn ich jetzt die Sichtbarkeit wechseln will, füge ich per JavaScript (irgend)einem Elternelement eine Klasse hinzu. Im Beispiel dem Element mit der ID »elternelement« .

        document.getElementById('elternelement').className = 'umgeschaltet';

        Dann sähe das DOM so aus:

        <div id="elternelement" class="umgeschaltet">  
         <div id="eins"></div>  
         <div id="zwei"></div>  
        </div>
        

        Jetzt kann ich CSS-Regeln schreiben, die bei gesetzter Klasse greifen. Sie können die Sichtbarkeit umkehren:

        .umgeschaltet #eins { display: none; }  
        .umgeschaltet #zwei { display: block; }
        

        Siehe:
        http://wiki.selfhtml.org/wiki/CSS/Selektoren/Klassenselektor
        http://wiki.selfhtml.org/wiki/CSS/Selektoren/Kombinator/Nachfahrenselektor

        Welches Elternelement du zum Umschalten der Klasse wählst, ist erst einmal egal. In obigem Beispiel habe ich ein extra div-Element hinzugefügt. Man kann aber auch ein Element verwenden, das das Dokument sowieso hat, wie etwa html oder body.

        In JavaScript liefert [link:https://developer.mozilla.org/de/docs/Web/API/document.documentElement@title=document.documentElement] liefert das html-Element, [link:https://developer.mozilla.org/en-US/docs/Web/API/document.body@title=document.body] liefert das body-Element. (Es geht auch anders, aber so ist es am einfachsten.)

        Kombinationsbeispiel, das document.body verwendet:
        http://codepen.io/molily/pen/fzxAL

        Zum übergang habe ich mich mal in den Link von die eingelesen
        Ich müsste da mit
        transition: opacity 1s
        arbeiten, hab aber nicht ganz verstanden, wie ich dann zuordne, dass das beim ein, bzw ausblenden benutzt werden soll.

        Die transition-Eigenschaft wird dem Element zugeordnet, bei dem sich die angegebene Eigenschaft ändert (hier opacity).

        Wenn das Ein- und Ausblenden mit display: block bzw. display: none erfolgt, dann lässt sich nicht so einfach eine CSS-Transition hinzufügen. Denn die Eigenschaft display ist nicht animierbar.

        Die Eigenschaft opacity ist animierbar, allerdings nimmt ein Element mit opacity: 0 immer noch Platz ein (es hat schließlich immer noch display: block o.ä.). Ich weiß daher nicht, ob dir das weiterhilft.

        Ich habe das obige Beispiel mal mit opacity anstatt display und einer Transition auf opacity gelöst:
        http://codepen.io/molily/pen/hactf

        Hier sollte der Unterschied klar werden. Eins und zwei liegen immer untereinander und nehmen Raum ein, selbst wenn Eins unsichtbar ist.

        JavaScript-Bibliotheken wie jQuery und Zepto haben Funktionen wie fadeIn und fadeOut, die erst die opacity animieren und letztlich, wenn sie 0 erreicht hat, die display-Eigenschaft auf »none« setzen (bei fadeIn natürlich umgekehrt).

        Grüße
        Mathias

    2. Hallo,

      <script type="text/javascript">
      <!--

      Du brauchst Scripte nicht mehr in <!-- … //--> einbetten, sofern du nicht Browser von 1995 unterstützen willst (kein Witz, alle neueren Browser brauchen das nicht).

      Eigentlich kann man es noch kürzer schreiben

        
      <script>.....</script>  
      
      
    3. @@molily:

      nuqneH

      Es gibt noch andere Methoden, die weniger JavaScript erfordern, nämlich das Umschalten einer Klasse mit JavaScript. Das Zeigen und Verstecken der Element wird dann über CSS-Regeln umgesetzt, die greifen, wenn die Klasse gesetzt ist oder nicht.

      Ja, das hab ich früher[tm] auch gesagt. Aber kann man das wirklich empfehlen? Wie bekommen AT-Nutzer angezeigt (angesagt), dass anderer Inhalt „sichtbar“ wird?

      Best practice dürfte sein, für initial nicht sichtbare Elemente das hidden-Attribut ins HTML zu schreiben. Per JavaScript entfernt man dies, wenn das Element sichtbar werden soll, und setzt hidden für Elemente, die nicht länger sichtbar sein sollen. (Das ist die empfohlene Verfahrensweise gegenüber aria-hidden.)

      Für ältere Browser, die hidden nicht nativ unterstützen, kann man bei Bedarf sowas wie
      [hidden] { display: none !important }
      bzw.
      [hidden] { visibility: hidden !important }
      ins Stylesheet schreiben.

      Qapla'

      --
      „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
      1. Hallo!

        Wie bekommen AT-Nutzer angezeigt (angesagt), dass anderer Inhalt „sichtbar“ wird?

        Ohne Optimierungen bekommen sie es nicht mit. Es gibt hier verschiedene Ansätze.

        Meistens ist es nicht nötig, dass nur ein Teilinhalt gleichzeitig existiert, man macht es nur aus gestalterischen Gründen und aus Gründen der Übersicht. Bei Akkordeon- und Aufklappnavigation z.B. lassen sich die Inhalte daher sauber auszeichnen und barrierefrei verstecken, sodass Screenreader die Inhalte nacheinander normal vorlesen.

        Wenn es nötig ist, Inhalte tatsächlich zu verstecken und erst nach einer Interaktion sichtbar zu machen, dann sollte per JavaScript der Fokus auf den neuen, eingeblendeten Inhalt gesetzt werden. Das geht mit tabindex="0" und der focus-Methode von Elementobjekten.

        Falls das Fokussieren eines bestimmten Elements nicht möglich ist, weil die Aktualisierung im Hintergrund erfolgt oder mehrere Elemente aktualisiert wurden, können ARIA Live-Regions verwendet werden. Dann bekommen Screenreader-Nutzer eine Ansage, dass sich das Element geändert hat.

        Mathias