Javascript

Tutorial: Toggle-Boxen mit jQuery

28. Juni 2009
von

Mit jQuery werden mittlerweile viele Websites verschönert, indem die Informationen nicht mehr, wie gewohnt, statisch in irgendeinem HTML-Element präsentiert werden; die Benutzer werden manchmal schon zur Interaktivität „gezwungen“. Eine Methode, so was mit jQuery zu erstellen, ist das Akkordion. Nachteil hierbei ist, dass standardmäßig jeweils nur eine Box geöffnet ist. Was ist aber, wenn ich mehrere offen halten will? Am besten baut man sich eigene Toggle-Boxen.

Fast genauso einfach, wie das Einbinden des Accordion Widgets vom jQuery UI, kann man sich mit Hilfe von jQuery einfache Toggle-Boxen selbst bauen. Genauso wie beim Accordion existieren die Boxen bereits zur Laufzeit und werden nur noch aus- oder eingeblendet. Die Boxen funktionieren auch ohne JavaScript und werden damit auch von Suchmaschinen ausgelesen.

togglebox img foto

Zu Beginn

Um jQuery und dessen mitgelieferte Funktionen zu nutzen, muss man die JavaScript-Datei im Head-Bereich einbinden, die man sich von der jQuery-Website herunterladen kann.

<script type="text/javascript" src="js/jquery.js"></script>

Hier müssen gegebenenfalls der Pfad und der Dateinamen angepasst werden.

Newsbox bauen

Der folgende Ausschnitt zeigt, wie das Steuerelement, das Bild, später als Knopf über der Newsbox eingebunden wird.

news open foto

<img src="images/box_news_open.gif" alt="News" id="boxhead_news" class="box_head" />

Der Klassenname ist später wichtig, damit wir die Grafiken ansprechen können, wenn diese angeklickt wurden. Die ID wird später auch noch relevant sein, denn daran wird unser Skript später erkennen, welche Box sich öffnen oder schließen soll.
Wir beginnen mit einer geöffneten Box, damit, wenn JavaScript deaktiviert ist, diese trotzdem angezeigt wird. Wichtig ist hier das Suffix des Dateinamens mit dem _open. Warum werden wir in dem Abschnitt „Toggle der Schaltfläche“ näher erklären.

Unsere eigentliche Newsbox bauen wir, wie folgt, auf:

<div id="box_news" class="boxes">
    <p>
        <strong>Beispieltitel</strong><br />
        Beispieltext
    </p>
</div>

An dieser Stelle ist es wichtig, dass die ID unserer Box, die gleiche Endung hat, wie unser Button oben (in diesem Fall also _news), sonst öffnet sich später die falsche Box oder gar keine.

Mit CSS formatieren wir noch mal grob unsere Boxen und unser Bild. Dazu habe ich im Head-Bereich die CSS-Datei eingebunden:

<link rel="stylesheet" type="text/css" href="css/style.css" />

und folgende Eigenschaften definiert:

.box_head{
    border: 1px solid #9C9C9C;
    margin-bottom: -6px;
    margin-top: 10px;
    width: 280px;
}
.boxes{
    width: 280px;
    border: 1px solid #9C9C9C;
}
.boxes p{
    padding: 20px;
}

Wenn die Box später beim Zuklappen „springt“, liegt es daran, dass jQuery die Höhe falsch berechnet und die Padding-Eigenschaft überspringt (tritt bei älteren jQuery-Versionen auf). Deswegen definiere ich an dieser Stelle nie ein padding-top oder padding-bottom als Eigenschaft für die Box. Deshalb gebe ich dem nächsten Kindelement (in unseren Beispiel dem P-Tag) hier das Padding-Attribut.

Box-Toggle programmieren

Die eigentliche Funktion, erfolgt in einer separaten Datei, welche wir ebenfalls im Head-Tag (nach der jQuery-Inkludierung) einbinden. Die Datei kann natürlich wieder beliebig benannt werden; hier muss dann nur der Pfad angepasst werden.

<script type="text/javascript" src="js/script.js"></script>

In die Datei schreiben wir nun folgenden Quellcode:

$(function(){
    $('.box_head').click(function(){
        idelem = $(this).attr('id');
        idelemdiv = idelem.replace('boxhead_', 'box_');
        $('#'+idelemdiv).slideToggle("normal");
    });
});

Ich werde das Skript hier erläutern. Wer sich auskennt, springt einfach zum nächsten Punkt. In der ersten Zeile steht die Kurzschreibweise von $(document).ready(function(){});

Der Inhalt dieser Funktion wird erst ausgeführt, wenn das Dokument komplett geladen ist und damit alle Elemente ansprechbar sind. Versucht man dieses ohne, kann kein Event-Listener an das Element gebunden werden, weil dieses einfach noch nicht existiert und die Box würde später nicht auf einen Klick reagieren. Wenn man wollte, könnte man die Sachen auch ohne einen aktiven Event-Listener programmieren, indem man im HTML-Quelltext eine onclick-Funktion auf das Bild legt.

In der zweiten Zeile binden wir ein Klick-Event mit einer anonymen Funktion an alle Elemente mit der Klasse box_head.
Die eigentliche anonyme Funktion ist in Zeile 3-6 ausprogrammiert.

In Zeile 3 wird die ID von dem jeweiligen Element (this), welches angeklickt wurde, geholt, um es später zu identifizieren. In Zeile 4 wird nun aus der ID das boxhead_ durch ein box_ ersetzt. An dieser Stelle wird es vielleicht klar, warum es so wichtig ist, dass das Bild, welches als Button fungiert, eine ähnliche ID wie die Box hat.

In Zeile 5 wird die Box nun mit der slideToggle-Funktion, welche von Haus aus von jQuery mitgeliefert wird, auf- oder zugeklappt (je nachdem, welchen Status sie vorher hatte). Als Parameter übergeben wir der Funktion die Einstellung für die Geschwindigkeit der Animation. Möglich sind hier als String zu übergeben “slow”, “normal” oder “fast” oder aber auch ein numerischer Wert für die Zeit in Millisekunden.

Nun müsste der Toggle-Effekt bereits funktionieren und die Box müsste auf- und zugehen, wie vorher angedacht.

Toggle der Schaltfläche

An dieser Stelle werden wir unser Skript erweitern, sodass das Bild vom Button beim Klick wechselt. Wir schreiben uns also folgende Funktion:

function change_boximage(elem){
    src = $('#'+elem).attr('src');
    if (src.indexOf("_open") >= 0){
        src = src.replace('_open', '_close');
    } else {
       src = src.replace('_close', '_open');
    }
    src = $('#'+elem).attr('src', src);
}

Diese Funktion macht nichts anderes, als sich den Inhalt des src-Attributs aus dem Image-Tag zu holen und nach einem „_open“ zu suchen. Deswegen ist es an dieser Stelle so wichtig gewesen, dass die Bilder mit _open oder mit _close als Suffix im Dateinamen benannt werden. Je nachdem, ob die Box also schon auf oder geschlossen ist, ersetzt sie entsprechend das src-Attribut. Anschließend weist die Funktion dem Image-Tag den Wert zu.

Möchte man die Bilder anders benennen, muss man an dieser Stelle die Parameter der Funktion “replace” dementsprechend verändern. Diese Funktion rufen wir wiederum in unserer anonymen Funktion von dem Click-Event unserer Box auf.

change_boximage(idelem);

Das sollte nun schon funktionieren, sofern zwei Bilder existieren, die korrekt benannt wurden.

Button-Mouse-Over erstellen

Spontan wird niemand darauf kommen, auf die Boxen zu klicken. Schon gar nicht, wenn sich der Cursor nicht verändert. In diesem Fall müssen wir dafür sorgen, dass der Cursor sich beim Mouse-Over verändert. Dies machen wir ebenfalls mit jQuery, indem wir das hover-Event von jQuery an die Boxen binden. Dieses schreiben wir mit in unsere Document-ready-Funktion, in der wir bereits den Event-Listener für die Boxen integriert haben.

$('.box_head').hover(
    function() {
        $(this).css('cursor', 'pointer');
    },
    function() {
        $(this).css('cursor', 'default');
    }
);

Das hover-Event ist glücklicherweise mit zwei Parametern ausgestattet: der erste für das Event mit Mouse-Over und das zweite für Mouse-Out. So können wir mit einer Funktion gleich auf beide Möglichkeiten reagieren.

Wir benutzen die css-Eigenschaft cursor und setzen hier beim MouseOver den Cursor auf den Wert pointer und setzen diesen beim MouseOut wieder auf default zurück. Dieser Aufruf erfolgt erneut in einer anonymen Funktion. Dies müsste sofort funktionieren und wir hätten damit die Grundfunktion der Toggle-Boxen komplett ausprogrammiert.

Wenn man jetzt möchte, kann man die Toggle-Boxen im HTML-Gerüst vervielfältigen. Man muss lediglich darauf achten, dass die IDs zusammen passen und keine doppelten vorkommen.

Toggle-Boxen im Einsatz

Wie man sieht, ist das eigentlich recht einfach gemacht. Mit CSS kann man nun viele Feinheiten vornehmen, um die Boxen zu stylen. Ihr könnt das Beispiel auch noch mal hier im Web finden und dort ausprobieren oder wenn bei Euch was nicht ganz funktioniert, eventuell auf Fehlersuche gehen.

Material zum Artikel

 foto

René Bärje

René (Jahrgang 1987) ist tätig als Webentwickler in einer Bremer Werbeagentur. Als gelernter Technischer Assistent für Informatik suchte René neue Herausforderungen und absolvierte eine Ausbildung zum Mediengestalter. René gibt Schulungen zu diversen Themen, führt viele Webprojekte an, schreibt Anwender-Dokumentationen und erstellt Kundenprojekte am laufenden Band.

13 Kommentare zu „Tutorial: Toggle-Boxen mit jQuery

  1. Stevie am 29. Juni 2009 um 08:20

    Hallo,
    die Boxen sind bei Aufruf der Seite alle geöffnet, ich möchte aber alle geschlossen haben…..

    Gruss

  2. Chris am 29. Juni 2009 um 09:18

    @Stevie

    schnellste mir bekannte Lösung hierfür:

    $(function(){
    $(‘.boxes’).hide();
    // hier das weitere Script von René Bärje
    });

    schöne Grüße

  3. René Bärje am 29. Juni 2009 um 09:11

    Hallo Stevie,

    damit die Toggle-Boxen trotzdem indizierbar bleiben und bei deaktiviertem JavaScript geöffnet sind, schließe ich die toggle-Boxen meist manuell im JavaScript.
    Ich spreche also in der onload-Function die Elemente einzeln an und sage, welches geschlossen werden soll.
    Wenn ich bestimmte Boxen haben will, dann eben einzeln.

    $(‘#box_news2′).slideToggle(“fast”);
    change_boximage(‘boxhead_news2′);

    Wenn ich alle Boxen geschlossen haben möchte, spreche ich diese einfach über die Klasse an.
    $(‘.boxes’).slideToggle(“fast”);

    über die Core-Funktion each von jQuery tausche ich dann noch die Grafiken aus.
    $(“.box_head”).each(function (i) {
    idelem = $(this).attr(‘id’);
    idelemdiv = idelem.replace(‘boxhead_’, ‘box_’);
    change_boximage(idelem);
    });

    Das wäre eine Variante (zu sehen auch unter http://www.drweb.de/magazin/wp-content/uploads/toggle_box1.zip), mit dem jetzigen Aufbau aus dem Tutorial.

    Gruß
    René

  4. jule_ am 29. Juni 2009 um 18:07

    Sehr angenehmes gut verständliches Tutorial für Anfänger, danke!

    Statt …
    [div id="box_news" class="boxes"]
    [p]
    [strong]Beispieltitel[/strong][br /]
    Beispieltext
    [/p]
    [/div]
    … würde ich das (semantisch richtigere) …
    [div id="box_news" class="boxes"]
    [h1]Beispieltitel[/h1]
    [p]
    Beispieltext
    [/p]
    [/div]
    … verwenden.

    Grüße aus Wien

    edit: Wäre fein wenn man in den Kommentaren spitze Klammern verwenden könnte. (Und wenn wir schon dabei sind: Eine Vorschaufunktion für die Kommentare wäre auch nicht schlecht)

  5. Christian am 30. Juni 2009 um 10:03

    Hi,

    schickes Tutorial! Es ist auf jeden Fall auch gut, dass die Boxen zunächst alle geöffnet sind – das beseitigt Barrieren bei abgeschaltenem JavaScript.
    Da es sich ja eigentlich um Listen handelt, wenn ich mir das Beispiel so anschaue, und einige eventuell gewillt sind dieses Konstrukt für eine Navigation zu verwerden wäre es vielleicht noch ratsam, statt der div-Container lieber eine unsortierte Liste zu verwenden. Speziell User mit Screenreadern können denn bequemer durch die Liste navigieren. Und als positiven Nebeneffekt erkennen auch Suchmaschinen die Einträge als zusammengehörigen Content.

    Grüße
    Christian

  6. FJ am 1. Juli 2009 um 12:04

    Ich hab da auch mal was gebastelt :-)
    http://www.flashjunior.ch/school/test/togglebox/

  7. Wolfgang Preller am 5. Juli 2009 um 13:47

    Entschuldigung, ich vergaß:
    cdu-aumuehle.de, Partei, Ausschüsse.
    Wolfgang Preller
    da ich den vorigen Text nicht sehen kann:
    es ging um die Zentrierung des Textes in den Boxen,
    habe alles mögliche versucht, leider keinen Erfolg,
    wie kann ich linksbündig erreichen?
    fragt und grüßt
    Wolfgang Preller

  8. Thomas am 6. Oktober 2009 um 01:00

    Hi,
    super Tutorial und gut zu gebrauchen :)

    Wie kann ich denn realisieren, dass wenn ein Container geöffnet wird, sich alle anderen Container im gleichen Moment schliessen?

    Gruß Thomas

  9. accordion effekt Problem - XHTMLforum am 22. November 2009 um 20:37

    [...] Div wieder zusammen. Hierf

  10. chaosmacherin am 20. Februar 2010 um 00:04

    für dummis wie mich ist das heir ziemlich schwierig beschrieben… ich versuchs jetzt schon eine weile und werde wohl auch noch weiter etwas probieren. :/

  11. rolan am 26. März 2010 um 00:32

    So etwas habe ich lange gesucht. Danke für verständliche Tutorial…
    Ich habe zwar noch tausend fragen, aber versuche ich erste die allein zu lösen.

  12. markus am 8. August 2010 um 00:58

    Was ist wenn ich jetzt in den toogles ein link aufrufe… komme auf ne neue seite ….. will aber den “offen zu” status von der letzten seite übernehmen… geht sowas mit jquery etwas übertragen?

    bsp, vertical tree navigation und wenn ich ein ast offen habe will ich das auf der nächsten seite übernehmen

    SUPER ANLIETUNG

    • Mel am 13. August 2010 um 09:23

      Hi!
      Der Validator sagt mir dass der Effekt durch die mehrfach angewandten id nicht valide ist. Kann man diesen Effekt auch mit Klassen erzielen? Wenn ja, bitte erklärt mir was ich alles austauschen muss. Ich möchte vermeiden aufgrund der “Invalidität” auf diesen schönen Effekt zu verzichten.

      Bitte um Antwort,
      Mel

      edit: Sorry Markus war nicht beabsichtigt auf deinen Beitrag zu antworten, hab ich mich vertan, sollte allgemein gepostet werden.

Ein Kommentar? Schön!

Wir freuen uns immer über Leser, die durch nützliche und konstruktive Beiträge zum Thema eine Diskussion anstoßen oder den Artikel mit weiteren Informationen anreichern. Alle Kommentare werden in diesem Sinne moderiert. Zum Kommentar-Fairplay gehört für uns auch der Einsatz von rel="nofollow". Bitte verwenden Sie zudem als Namen weder eine Domain noch ein spamverdächtiges Wort. Vielen Dank!

*