Stand: 24.04.2022

Lernziele

jQuery ist eine kostenlose Javascript-Bibliothek, die den Umgang mit DOM-Elementen erleichtert und zusätzlich viele Effekte anbietet. jQuery nutzt dabei die wohlbekannte CSS-Syntax zur Selektion.

jQuery ist sicher die populärste Bibliothek im WWW für die Frontend-Programmierung, wurde von John Resig entwickelt und 2006 veröffentlicht. jQuery ist nicht verwechseln mit JQuery UI und jQuery Mobile. Letztere sind eigenständige Projekte mit teils ganz anderer Zielsetzung.

Als Literatur empfehlen wir folgendes Buch, das besonders Design-affine Menschen anspricht:

Jon Duckett (2015) JavaScript & jQuery: Interaktive Websites entwickeln, Wiley.

10.1 Grundlegendes

10.1.1 jQuery einbinden

jQuery ist eine JavaScript-Bibliothek. Eine Bibliothek (engl. library) ist eine Datei mit lauter (JavaScript-)Funktionen, die Sie für Ihre Programmierung verwenden können. Das heißt: Sie programmieren in JavaScript und werden dabei durch zusätzliche Funktionalität unterstützt.

Damit Ihr Code funktioniert, muss der Browser die Bibliothek laden. Um dies zu tun, hat man zwei Optionen.

jQuery-Datei selbst bereitstellen

Sie können die Bibliothek als Datei von jquery.com runterladen und anschließen auf Ihre Webseite hochladen. Auf der Webseite können Sie zwischen "compressed" und "uncompressed" unterscheiden. Ersteres bedeutet lediglich, dass alle Leerzeichen und Zeilenumbrüche entfernt sind. Das nennt man auch "minifizieren" und wird mit dem Kürzel "min" angezeigt.

In Ihrer HTML-Datei geben Sie den Ort Ihrer Datei an, zum Beispiel:

<script src="pfad-zu-jquery/jquery-3.2.1.min.js"></script>

Das Einbindung von JavaScript macht man am besten ganz am Ende des body-Blocks, also direkt vor dem schließenden Tag </body>.

Externe jQuery-Datei verlinken (CDN)

Alternativ können Sie auf eine Datei verweisen, die bei einem CDN (content delivery network) liegt, z. B. bei Google. Der Vorteil ist, dass die Bibliothek evtl. schon im Cache-Speicher der Browsers liegt, weil andere Webseiten das selbe CDN bemüht haben.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Auch hier gilt: Das Einbindung von JavaScript macht man am besten ganz am Ende des body-Blocks, also direkt vor dem schließenden Tag </body>.

Vorsicht: Es gibt eine Variante, die sich "slim" nennt. Diese stellt einige wichtige Effekte nicht zur Verfügung.

jQuery testen

Um herauszufinden, ob jQuery "da" ist, laden Sie die Seite im Browser und öffnen die JavaScript-Konsole. Geben Sie ein:

jQuery

Die Reaktion sollte klar machen, dass es sich um ein Objekt handelt.

Die Versionsnummer bekommen Sie mit

jQuery().jquery

Eigener Code

jQuery-Code wird wie JavaScript-Code eingebunden, denn es ist ja JavaScript.

Also entweder direkt im HTML:

<script>
  // Ihr Code
</script>

Oder als Link auf separate Datei z. B. "script.js" im Unterverzeichnis "/js".

<script src="js/script.js"></script>

In beiden Fällen ist es wichtig, dass der eigene Code erst nach der Stelle kommt, wo die Bibliothek eingebunden wird.

Da auch jQuery immer noch JavaScript ist, hat Ihre Datei die Endung .js.

Basis-Code

Hier ein Beispiel für eine minimale HTML-Datei, die jQuery von Google lädt und dann eine Ausgabe macht:

<!DOCTYPE html>
<html lang="de">
  <head>
    <meta charset="utf-8">
    <title>JavaScript</title>
  </head>
  <body>
    <p>jQuery running...</p>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
      $(document).ready(function(){
        console.log("Hello, jQuery " + jQuery().jquery + "!");
      });
    </script>
  </body>
</html>

Sie sollten auf der Konsole sehen:

Hello, jQuery 3.3.1!

Es wird empfohlen, den jQuery-Code mit diesem Gerüst zu umgeben:

$(document).ready(function(){
  ...
});

So wird sichergestellt, dass der Code erst ausgeführt wird, wenn die Seite vollständig geladen ist.

10.1.2 jQuery-Befehle

Ein jQuery-Befehl macht in der Regel folgendes:

  1. ein oder mehrere HTML-Elemente auswählen
  2. eine Aktion auf diesen Elementen ausführen (z. B. unsichtbar schalten)

Die Basis-Syntax ist:

$(selektor).aktion();

Beispiele sind:

$('p').hide();
$('.test').hide();

Diese Form

$('p').hide();

ist eine Abkürzung für

jQuery('p').hide();

Es wird zu 99% die Form mit dem $ benutzt.

Um sicher zu stellen, dass Ihr Code erst dann ausgeführt wird, wenn die Seite komplett geladen ist, betten Sie den gesamten Code ein in:

$(document).ready(function(){

    // jQuery-Code, zum Beispiel:
    alert('Hallo');

});

10.2 jQuery und DOM

10.2.1 Selektion und das jQuery-Objekt

Das besondere an jQuery ist, dass Sie mit den Ihnen bekannten CSS-Selektoren arbeiten können. Ergebnisse werden in einem speziellen jQuery-Objekt gespeichert, das so ähnlich wie ein JavaScript-Array funktioniert, aber kein Array ist (es ist auch keine HTMLCollection und auch keine NodeList).

Wie in CSS können Sie Elemente (p, h1, ul, a etc.), Klassen (mit Punkt) und IDs (mit #) auswählen. Als Rückgabe bekommen Sie ein jQuery-Objekt, das alle gefundenen Elemente enthält.

Zum Beispiel alle Absätze im Dokument:

$('p')

Alle Elemente mit Klasse test:

$('.test')

Alle Absätze innerhalb eines Elements der Klasse test:

$('.test p')

Das Element mit ID special:

$('#special')

In jQuery ist es - wie in JavaScript - egal, ob Sie einfache oder doppelte Anführungszeichen verwenden, denn es handelt sich ja immer noch um JavaScript.

Da ein jQuery-Objekt eine Menge von Elementen enthalten kann, kann man einzelne Elemente mit der bekannten Array-Notation beziehen:

$('p')[0]

Sie bekommen hier ein Element-Objekt, wie Sie es auch dem vorigen Kapitel kennen.

10.2.2 Umgang mit dem jQuery-Objekt

(Mehr zum jQuery-Objekt auch in der offiziellen Doku: The jQuery Object)

Das jQuery-Objekt ist zusammen mit speziellen jQuery-Funktionen ein mächtiges Instrument. Auch wenn das jQuery-Objekt mehrere Elemente enthält, kann man mit einer einzigen Funktion alle diese Elemente ansprechen oder anders gesagt: die Funktion wird automatisch auf jedes Element im jQuery-Objekt angewandt.

Wir zeigen das am Beispiel der Funktion hide (verstecken). Zunächst gibt uns ein Selektor ein jQuery-Objekt zurück, das alle Absätze im Dokument enthält:

$('p')

Wenn wir die jQuery-Aktion hide anwenden, wird diese Aktion auf jedem Element ausgeführt. Das heißt, Sie müssen weder Schleife noch forEach einsetzen, sondern schreiben einfach:

$('p').hide();

So verstecken Sie mit einer Zeile Code alle Absätze im Dokument. Wichtig ist, dass jQuery-Funktionen wie hide auch nur auf jQuery-Objekten arbeiten können und nicht auf den regulären Element-Objekten, die wir im letzten Kapitel kennen gelernt haben.

Sie sehen das, wenn Sie auf ein einzelnes Element zugreifen und hide verwenden wollen.

$('p')[0].hide(); // FEHLER!

Da hier ein Element-Objekt zurückgegeben wird, können Sie keine jQuery-Funktion verwenden, sondern nur die aus dem letzen Kapitel bekannten JavaScript-Mechanismen, z. B.

$('p')[0].style.backgroundColor = 'yellow';

Wenn wir die vielen Funktionen der jQuery-Welt auch bei einzelnen Elementen nutzen möchten, müssen wir eine andere Art des Zugriffs wählen.

Auf Elemente im jQuery-Objekt zugreifen

Die Grundidee ist, dass wir ein Element aus einem jQuery-Objekt herausgreifen und dies wieder als jQuery-Objekt (das nur ein Element enthält) zurückbekommen. Damit das funktioniert, muss man anstatt der Array-Notation die Methode eq() (für equals) verwenden. Diese gibt das Element zurück, das mit dem Index angegeben ist (startet bei 0). Um den ersten Absatz im Dokument zu verstecken schreiben wir also:

$('p').eq(0).hide();

Zusätzlich gibt es die Methoden first und last, die jeweils das erste/letzte Element zurückgeben:

$('p').first().hide();
$('p').last().hide();

Beachten Sie, dass die Rückgaben für die obigen Funktionen auch wieder jQuery-Objekte sind, d. h. auch diese Objekte sind im Grunde Listen, nur eben mit der Länge eins. Es ist in jQuery also irrelevant, ob Sie mit einzelnen Elementen oder einer Liste arbeiten. In der Praxis ist das sehr sinnvoll und spart eine Menge Code.

Alle Elemente durchlaufen

Wenn es eine jQuery-Aktion gibt, die Sie anwenden möchten, müssen Sie gar nicht alle Elemente eines jQuery-Objekts durchlaufen. Gibt es aber keine solche Funktion oder Sie möchten komplexere Handlungen durchführen, brauchen Sie eine Schleife oder einen Mechanismus wie forEach.

Bei einem jQuery-Objekt funktioniert forEach aber nicht, da es ja kein JavaScript-Array ist. Stattdessen gibt es eine eigene Methode each, die ähnlich arbeitet. Wenn man auf jeder Entität einer Liste eine Funktion ausführen möchte, kann man das so schreiben:

$("h1").each(function(){
  console.log($(this).text());
});

Das $(this) verweist dabei auf das aktuell durchlaufene jQuery-Element.

10.2.3 Events und Event-Handling

Events sind Ereignisse, die z. B. vom User ausgelöst werden, z. B.

Diese Ereignisse sind gleichzeitig jQuery-Aktionen, mit denen Sie eine eigene Funktion an Elemente binden können. Die Funktion nennt man auch hier Handler.

Hier wird für das Click-Event eine Funktion (= Event-Handler) an alle p-Elemente gebunden:

$('p').click(function(event){
  console.log(event);
});

Ähnlich wie bei JavaScript wird der Handlerfunktion ein Event-Objekt übergeben, das Informationen wie Zeitpunkt des Clicks enthält. Alle Informationen dazu finden Sie in der Event Object API.

    $('p').click(function(event){
        console.log(event.timeStamp);
    });

Die Zeit wird in Millisekunden seit dem 1.1.1970 gemessen.

Wenn Sie diese Infos nicht benötigen, definieren Sie den Handler einfach ohne Parameter:

$('p').click(function(){
  // Ihr Code!!
});

Innerhalb Ihres Event-Handlers können Sie mit $(this) auf das Element zugreifen, das den Event ausgelöst hat:

$('p').click(function(){
  $(this).hide();
});

10.2.4 Elemente ändern

Inhalte ändern

Sie können mit jQuery natürlich auch auf Inhalte zugreifen und diese ändern. Im Gegensatz zu DOM-Objekten - wo man mit Eigenschaften arbeitet - funktioniert der Zugriff in jQuery über Getter- und Setter-Methoden.

Den HTML-Text bekommen Sie mit der Getter-Methode html:

foo = $('p').html();

Zu beachten ist hier, dass nur der HTML-Text des ersten gefundenen Elements zurückgegeben wird. Da jQuery-Objekte immer mehrere Elemente enthalten müssen, müssen Sie bei jeder Funktion wissen, wie damit umgegangen wird. Bei text wird z. B. der Text aller Elemente zusammenkopiert (s. u.).

Vergleichen wir den Code mit JavaScript:

document.getElementsByTagName('p')[0].innerHTML

Sie ändern HTML-Elemente in jQuery mit der Setter-Methode html. Auch hier ist Vorsicht angesagt. Beim Setzen von Inhalten werden alle gefundenen Elemente geändert (nicht nur das erste):

$('p').html('I have been <strong>clicked</strong>!');

Möchten Sie nur das erste Element ändern, müssen Sie first oder eq einbauen:

$('p').eq(0).html('I have been <strong>clicked</strong>!');

Auch hier der Vergleich zu JavaScript:

document.getElementsByTagName('p')[0].innerHTML =
  'I have been <strong>clicked</strong>!'

Sie sehen, dass Getter- und Setter-Methode genau gleich heißen und sich nur darin unterscheiden, dass die Setter-Methode einen Parameter erwartet, nämlich den neuen Wert.

Wollen Sie nur den Text ohne HTML-Markup, schreiben Sie:

foo = $('h1').text();

Wie bereits erwähnt, wird hier der Text aller gefundenen Elemente zusammengeklebt.

Oder Sie setzen Text (von allen gefundenen Elementen):

$('h1').text('I have been clicked!');

Schauen Sie in der jQuery-Doku nach, ob Sie den unterschiedlichen Umgang mit den Elementen herauslesen können: html() | text()

Wenn Sie mit einen Klick auf die Überschrift den Text ändern wollen, schreiben Sie z. B.

$('h1').click(function(){
  $(this).html('Das ist <em>schräg</em>!');
});

Nach diesem Befehl reagieren alle h1-Überschriften auf einen Klick mit der Änderung der Überschrift.

Styling ändern

Das Styling (CSS) ändern Sie mit:

$('h1').css('color', 'red');

Auch das können Sie in einer Interaktion verwenden: Wir möchten, dass der Hintergrund der Überschrift gelb markiert wird, wenn wir mit der Maus in das Element fahren:

$('h1').mouseenter(function(){
  $(this).css('background-color', 'yellow');
});

Wenn wir wollen, dass bei Verlassen des Elements der Hintergrund wieder weiß wird, schreiben wir:

$('h1').mouseleave(function(){
  $(this).css('background-color', 'white');
});

Klassen ändern

Nehmen wir an, wir haben das folgende CSS vorliegen:

.important {
  font-weight: bold;
  font-size: 40px;
}

.blue {
  color: blue;
}

Sie können eine Klasse hinzufügen mit addClass():

$("button").click(function(){
  $("h1,h2,p").addClass("blue");
  $("div").addClass("important");
});

Sie können eine Klasse entfernen mit removeClass():

$("button").click(function(){
  $("h1,h2,p").removeClass("blue");
});

Attribute ändern

Klassen sind Attribute, aber es gibt noch weitere Attribute wie "href" oder "src" und natürlich der ID. Sie greifen mit attr auf ein Attribut zu. Bei mehreren Elementen im jQuery-Objekt wird das erste genommen:

$('a').eq(0).attr('href');

Auch hier haben Sie eine Setter-Variante:

$('a').eq(0).attr('href', 'index.html');

Hier werden alle Elemente verändert.

10.2.5 Verkettung

Die Ausführung einer Funktion gibt wieder das ausgewählte Objekt zurück, so dass Befehle mit Punktnotation verkettet werden können:

$("#p1").css("color","red").slideUp(2000).slideDown(2000);

Dies ist nicht nur möglich, sondern auch gute Praxis!

Ein Vorteil gegenüber der nachfolgenden Lösung ist, dass nur einmal gesucht wird (Selektion), was Rechenzeit spart.

$("#p1").css("color","red");
$("#p1").slideUp(2000);
$("#p1").slideDown(2000);

Abgesehen davon wird der Code durch Verkettung kürzer und - wenn man sich daran gewöhnt hat - auch besser lesbar.

10.2.6 Im Baum navigieren

Wie auch in JavaScript möchten wir im DOM-Baum navigieren. Schauen wir uns nochmal ein Beispiel für einen DOM-Baum an:

Beispiel für einen DOM-Baum

Die Wurzel des Dokuments bekommen Sie bei jQuery mit

$(document)

Eltern

Mit parent() bekommen Sie den einen direkten Elternknoten, den jedes Element hat.

$("span").parent();

Mit parents() bekommen Sie nicht nur den direkten Elternknoten, sondern auch dessen Elternknoten usw.

Im folgenden Beispiel sehen Sie, dass man in den Klammern auch noch einen Filter angeben kann.

$("span").parents("ul");

Als Anwendungsbeispiel schauen wir uns eine Liste in HTML an:

<ul>
  <li>Johnny</li>
  <li>Lonny</li>
  <li>Donny</li>
</ul>

Vielleicht möchten Sie folgenden Mausover-Effekt erreichen: Wenn der Mauszeiger über ein Item fährt, soll das Item gekennzeichnet werden (z. B. rote Schrift). Gleichzeitig soll aber auch die gesamte Liste markiert werden (z. B. gelber Hintergrund).

Dann schreiben Sie

$('li').mouseenter(function() {
  $(this).css('color', 'red');
  $(this).parent().css('background-color', 'yellow');
});

Außerdem müssen wir das rückgängig machen, wenn die Maus das Item verlässt:

$('li').mouseleave(function() {
  $(this).css('color', 'black');
  $(this).parent().css('background-color', 'white');
})

Kinder / Nachfahren

Mit children() bekommen Sie alle Kindknoten:

$("div").children();

Auch hier können Sie zusätzlich filtern:

$("div").children(".special");

Der Befehl find() sucht in allen Nachfahren, also allen Kindern und Kindeskindern:

$("div").find("span");

In der Anwendung verwenden Sie diese Methoden, wenn Sie in einem übergeordneten Container ein Event auffangen (z. B. Klick), aber alle enthaltenen Elemente stylen wollen (mit einer nicht-vererbbaren Eigenschaft).

Hier bekommen alle Kindelemente einen Rahmen:

$('div').click(function() {
    $(this).children().css('border-style', 'solid');
})

So bekommen alle Kinder und Kindeskinder einen Rahmen:

$('div').click(function() {
    $(this).find('*').css('border-style', 'solid');
})

Geschwister

Mit siblings() bekommen Sie alle Geschwisterknoten. In einer Baumdarstellung wie oben sind das alle benachbarten Knoten mit dem selben Elternknoten.

$("h2").siblings();

Mit next() bekommen Sie den nächsten (rechten) Geschwisterknoten:

$("h2").next();

Mit nextAll() bekommen Sie alle Geschwisterknoten, die rechts liegen:

$("h2").nextAll();

Sie können in die Klammer noch einen Filter stecken, um z. B. nur alle Absätze zu bekommen, die unter dem h2 liegen:

$("h2").nextAll("p");

Ähnlich, aber nach links, funktionieren prev() und prevAll().

Nehmen wir an, Sie möchten den Text unter h2 verstecken bzw. zeigen, wenn Sie auf die Überschrift klicken. Dann schreiben Sie:

$('h2').click(function() {
    $(this).nextAll('p').toggle();
})

Listen filtern

Viele Selektoren und Funktionen liefern Listen zurück, z. B. parents(), siblings(), nextAll() usw. Es ist möglich, mit filter() in diesen Listen zu suchen.

$("p").filter(".intro");

Mit not() können Sie auch die Liste ausdünnen:

$(document).find('*').not('meta');

10.3 Effekte

Neben dem eleganten Ansteuern von DOM-Elementen stellt jQuery auch eine Reihe von wichtigen Effekten bereit, die sehr bequem eingebaut werden können.

10.3.1 Basiseffekte

Hide/Show

Wenn Sie auf Events reagieren reagieren möchten, indem Sie z. B. ein Bildschirmelement aus- oder einschalten, können Sie hide() und show() verwenden:

$(this).hide();
$(this).show();

Es gibt auch toggle(), das ein Element zeigt, wenn es versteckt ist und umgekehrt. Es ist also so eine Art Schalter:

$(this).toggle();

Fade

Mit fadeIn und fadeOut können Sie ein Element weich ein- und ausblenden:

fadeIn(speed, callback)
fadeOut(speed, callback)

Die Geschwindigkeit kann optional gesetzt werden (in Millisekunden, also 1000 für eine Sekunde).

Mit "callback" ist eine Funktion gemeint, die Sie übergeben können und die nach Ende des FadeIn ausgeführt wird.

Auch hier haben Sie eine Schalterfunktion:

fadeToggle(speed, callback)

Um zu einer bestimmten Deckkraft (engl. opacity) zu faden, schreibt man:

fadeTo(speed, opacity, callback)

0 ist transparent, 1 ist voll sichtbar.

Slide

Schließlich können Sie ein Element durch "rollen" öffnen oder schließen:

slideDown(speed, callback)
slideUp(speed, callback)
slideToggle(speed, callback)

10.3.2 Animate

Mit animate() können Sie verschiedene CSS-Eigenschaften (Abstand vom Rand, Höhe, Breite, ...) animieren. Interessant ist insbesondere, dass man mehrere Eigenschaften gleichzeitig animieren kann.

Allgemein sieht das so aus (wobei im Bereich 'css' mehrere Eigenschaften stehen können):

animate({ css }, speed, easing, callback);

Ein Beispiel:

$("button").click(function(){
  $("div").animate({marginLeft:'250px'}, 2000, 'swing');
});

Ein paar Dinge muss man beachten:

Wie erwähnt können mehrere Eigenschaften gleichzeitig animiert werden:

$("button").click(function(){
  $("div").animate({
    left:'250px',
    opacity:'0.5',
    height:'150px',
    width:'150px'
  });
});

Relative Werte (d. h. relativ zum aktuellen Wert) können Sie mit += und -= angeben:

$("button").click(function(){
  $("div").animate({
    left:'250px',
    height:'+=150px',
    width:'+=150px'
  });
});

Mehrere Animationen werden hintereinander ausgeführt, wie hier z. B.:

$("button").click(function(){
  var div=$("div");
  div.animate({height:'300px',opacity:'0.4'},"slow");
  div.animate({width:'300px',opacity:'0.8'},"slow");
  div.animate({height:'100px',opacity:'0.4'},"slow");
  div.animate({width:'100px',opacity:'0.8'},"slow");
});

Man kann auch die Punktnotation ausnutzen:

div.animate({height:'300px',opacity:'0.4'},"slow").animate({width:'300px',opacity:'0.8'},"slow");

Wie oben kann man beliebig viele Animationen aneinander reihen.

10.3.3 Browser-Events und Smooth Scrolling

Neben den bereits erwähnten Events gibt es noch die folgenden Browser-Events:

Bei beiden Events kann man einen Handler an das sogenannte window-Objekt binden.

Das resize löst den Handler aus, sobald die Fenstergröße vom User verändert wird.

$(window).resize(function() {
  console.log('resized...' + $(window).width());
});

Das scroll löst den Handler aus, sobald der User im Fenster scrollt.

$(window).scroll(function() {
  console.log('scrolling');
});

Mit Hilfe dieser Funktionen können Sie z. B. Schaltflächen verändern, wenn das Fenster sich verändert oder der User scrollt.

Smooth Scrolling

Smooth Scrolling bezieht sich auf den Effekt, dass beim Anklicken eines seiteninternen Links nicht hart gesprungen wird, sondern das Fenster zur gewünschten Stelle scrollt.

Für ein weiches Scrolling benötigen wir drei Funktionen

Smooth Scrolling funktioniert prinzipiell so:

Schauen Sie zum Beispiel bei w3schools (einfaches Beispiel) oder bei CSS-Tricks (etwas allgemeineres Beispiel) nach, wie man Smooth-Scrolling realisiert.

Update 2020: Mittlerweile ist smooth scrolling trivial geworden. Man kann es einfach in CSS einschalten:

    html {
      scroll-behavior: smooth;
    }

Die obige Übung ist dennoch interessant, um den Event-Mechanismus zu verstehen.

10.4 Praktische Beispiele

10.4.1 Akkordeon

Wir schauen uns jetzt an, wie wir das Akkordeon aus dem letzten Kapitel mit jQuery realisieren:

Beispiel Akkordeon aufgeklappt

Layout

In HTML sieht die Struktur wie folgt aus:

<div class="accordion">
  <h2>Vorlesung 1</h2>
  <div class="section">
    <p>
      Lorem ipsum ...
    </p>
    <p>
      Lorem ipsum ...
    </p>
  </div>

  <h2>Vorlesung 2</h2>
  <div class="section">
    <p>
      Lorem ipsum ...
    </p>
    <p>
      Lorem ipsum ...
    </p>
  </div>

  ...
</div>

Programmierung

Wir wollen auf einen Klick auf eine h2-Überschrift reagieren, indem wir

  1. alle Abschnitte zunächst zuklappen und
  2. den einen Abschnitt hinter dem angeklickten h2-Element aufklappen.

In jQuery benötigt man für jeden Schritt eine Zeile Code:

$('.accordion h2').click(function() {
  $(this).siblings('div').hide();
  $(this).next().show();
});

Im ersten Schritt möchten wir alle Geschwisterknoten vom H2-Element auswählen, aber eben nur die DIV's (und nicht die anderen H2) und diese dann ausschalten mit hide. In der zweiten Zeile zeigen wir dann das DIV, welches auf das angeklickte H2 folgt.

Hier der Code zum Ausprobieren:

Akkordeon mit jQuery →

Zum Vergleich den JavaScript-Code. Zum Zuklappen aller Abschnitte hatten wir die Funktion collapseAll definiert:

document.querySelectorAll('.accordion h2').forEach(function(x) {
  x.addEventListener('click', function() {
    collapseAll();
    this.nextElementSibling.style.display = 'block';
  });
});

function collapseAll() {
  document.querySelectorAll('.accordion .section').forEach(function(el) {
    el.style.display = 'none';
  });
}

Sie würden vielleicht zustimmen, dass die jQuery-Variante nicht nur weniger Code erfordert, sondern auch deutlich lesbarer ist.

Toggle-Variante

Eine Variante des Akkordeons lässt die offenen Abschnitte einfach geöffnet, d. h. die erste Zeile fällt weg:

$('.accordion h2').click(function() {
  $(this).next().show();
});

Wenn Sie jetzt aber ein zweites Mal auf die Überschrift klicken, soll der Abschnitt wieder verschwinden, beim nächsten Mal wieder auftauchen etc. Dies lässt sich ganz einfach mit der Aktion toggle ausdrücken:

$('.accordion h2').click(function() {
  $(this).next().toggle();
});

Hier nochmal zum Ausprobieren:

Akkordeon Toggle-Variante →

Roll-Effekt hinzufügen

Wir möchten jetzt das angeklickte Segment ausrollen mit Hilfe von slideDown. Wir ändern unseren Code wie folgt.

$('.accordion h2').click(function() {
  //$(this).parent().children(".section").css("display", "none");
  $(this).next().slideDown();
});

Da das Verschwinden der bislang aufgeklappten Segmente nicht zu unserer Animation passt, haben wir die Zeile auskommentiert. Wir haben noch das Problem, dass bei mehrmaligem Anklicken der Überschrift, das Segment immer neu ausgerollt wird. Wir wollen also vorher testen, ob das Segment nicht schon sichtbar ist. Dazu verwenden wir die Methode css.

$('.accordion h2').click(function() {
  if ($(this).next().eq(0).css('display') == 'none') {
    $(this).next().slideDown();
  }
});

Wir können jetzt auch sagen: Wenn das Segment aufgerollt ist und ich klicke auf die Überschrift, dann soll das Segment wieder zurollen:

$('.accordion h2').click(function() {
  if ($(this).next().eq(0).css('display') == 'none') {
    $(this).next().slideDown();
  } else {
    $(this).next().slideUp();
  }
});

Eine letzte Herausforderung ist es, immer nur ein Segment zu zeigen. Dazu müssen wir, bevor wir ein Segment öffnen, alle anderen Segmente schließen. Wir müssen dabei nicht extra checken, ob ein Segment offen ist. Die Methode slideUp macht einfach nichts, wenn das Segment unsichtbar ist.

$('.accordion h2').click(function() {

  // Alle anderen Segmente schließen
  $(this).siblings('h2').each(function() {
    $(this).next().slideUp();
  });

  if ($(this).next().eq(0).css('display') == 'none') {
    $(this).next().slideDown();
  } else {
    $(this).next().slideUp();
  }
});

Hier finden Sie die Seite mit der Slide-Funktionalität:

Akkordeon mit Slide →

10.4.2 Panel mit Reitern

Auch die Reiter-gesteuerte Anzeigen von Inhalten, die wir in JavaScript kennengelernt haben, möchten wir in jQuery umsetzen:

Panel mit Reitern, Startbild

Panel mit Reitern (jQuery) →

Layout

Das Layout is genauso wie in der JavaScript-Version.

<div class="reiter">
  <ul>
    <li class="active"><a href="eins">Pusteblume</a></li>
    <li><a href="zwei">Hase</a></li>
    <li><a href="drei">Dinosaurier</a></li>
    <li><a href="vier">Turm</a></li>
  </ul>

  <div id="eins">
    <h1>Pusteblume</h1>
    <p>
      Lorem ipsum ...
    </p>
  </div>
  ...
</div>

Programmierung

Auch hier haben wir folgende Schritte

  1. An jeden Reiter einen Handler binden
  2. Im Handler
    • den angeklickten Reiter auf aktiv schalten
    • den dazugehörigen Content anzeigen (alle anderen verstecken)
  3. Content vom ersten Reiter anzeigen

Zunächst binden wir also die Reiter. Auch hier setzen wir das Standardverhalten von Links mit preventDefault außer Kraft:

$('.reiter li').click(function(event) {
  event.preventDefault();
  ...
});

Als nächstes setzen wir den angeklickten Reiter auf aktiv:

$('.reiter li').click(function(event) {
  event.preventDefault();

  $(this).parent().children().removeClass('active');
  $(this).addClass('active');
  ...
});

Jetzt verstecken wir erstmal alle Inhalte und stellen anschließend nur den Content auf sichtbar, der zu dem angeklickten Reiter gehört:

$('.reiter li').click(function(event) {
  ...

  $('.reiter div').hide();
  let ref = $(this).find('a').attr('href');
  $('#'+ref).show();
});

Zum Schluss schalten wir den Content vom ersten Reiter auf sichtbar. Das soll immer beim Laden der Seite geschehen:

$('.reiter>div').eq(0).show();

Hier nochmal der komplette Code:

$(document).ready(function(){
  $('.reiter li').click(function(event) {
    event.preventDefault();
    $(this).parent().children().removeClass('active');
    $(this).addClass('active');
    $('.reiter div').hide();
    let ref = $(this).find('a').attr('href');
    $('#'+ref).show();
  });
  $('.reiter>div').eq(0).show();
});

Zum Anschauen und Runterladen:

Panel mit Reitern (jQuery) →

10.5 Vergleich JavaScript und jQuery

Wir sehen uns zentrale Funktionen in JavaScript und jQuery in direkter Gegenüberstellung an.

10.5.1 DOM-Elemente

JS

In JavaScript haben wir mit den folgenden Objekten zu tun:

Beispiele:

    el = document.getElementById('totop') // HTMLElement
    liste = document.getElementsByTagName('h2') // HTMLCollection
    nodes = document.querySelectorAll('h2') // NodeList

jQ

In jQuery hat man genau ein Objekt mit einer Liste, die eventuell nur ein Element enthält.

Eine Variable, die ein jQuery-Objekt enthält, wird manchmal mit führendem Dollarzeichen geschrieben, um dies zu signalisieren.

Beispiel:

    $liste = $('h1') // jQuery-Objekt

10.5.2 Listen durchlaufen

JS

Für eine HTMLCollection muss man eine For-Schleife bemühen:

    let list = document.getElementsByTagName('h1');
    for (let i = 0; i < list.length; i++) {
      console.log(list[i].innerText);
    }

For eine NodeList gibt es das forEach:

    document.querySelectorAll('h1').forEach(function(el) {
      console.log(el.innerText);
    });

jQ

For das jQuery-Objekt gibt es das each:

    $('h1').each(function(){
      console.log($(this).text());
    });

10.5.3 Event-Handling

JS

In JavaScript verwenden Sie addEventListener und greifen mit this auf das auslösende Element zu.

    document.getElementsById('foo').addEventListener('click',
    function(event) {
        alert('You clicked: ' + this.innerText);
    });

Der Parameter event ist ein Objekt vom Typ MouseEvent.

jQ

In jQuery nutzt man die Funktion click und greift mit $(this) auf das auslösende Element - als jQuery-Objekt - zu:

    $('#foo').click(function(event) {
        $(this).hide();
    });

Der Parameter event ist ein Objekt vom Typ Event Object.

10.5.4 Inhalte und Styling ändern

JS

Zugriff auf den Text eines Elements:

    console.log(document.getElementsByTagName('h1')[0].innerText);

Änderung des Textes:

    document.getElementsByTagName('h1')[0].innerText = "Foo";

Änderung des Stylings:

    document.getElementsByTagName('h1')[0].style.backgroundColor = 'yellow';

Zugriff auf das Styling:

    console.log(getComputedStyle(document.getElementsByTagName('h1')[0]).color);

jQ

Zugriff auf den Text eines Elements:

    console.log($('h1').eq(0).text());

Änderung des Textes:

    $('h1').eq(0).text("Foo");

Änderung des Stylings:

    $('h1').eq(0).css('background-color', 'yellow');

Zugriff auf das Styling:

    console.log($('h1').eq(0).css('color'));

10.5.5 Zugriff auf Klassen und IDs

JS

Alle Klassen eines Elements beziehen:

    console.log(document.getElementsByTagName('div')[0].classList);

Eine Klasse hinzufügen:

    document.getElementsByTagName('div')[0].classList.add('foo');

Einen ID setzen:

    document.getElementsByTagName('div')[0].id = 'special'

jQ

Alle Klassen eines Elements beziehen:

    console.log($('div').eq(0).attr('class'));

Eine Klasse hinzufügen:

    $('div').eq(0).addClass('foo');

Einen ID setzen:

    $('div').eq(0).attr('id', 'special');

10.6 Übungen

10.6.1 Erste Schritte

(E1) jQuery einbinden

Schreiben Sie eine HTML-Datei, in der Sie einen script-Teil einbetten (am Ende des Body). Davor binden Sie jQuery ein, entweder eine eigene Datei oder über einen Link auf ein CDN.

Als Code schreiben Sie:

console.log("Hier läuft jQuery-Version " + jQuery().jquery);

Laden Sie die HTML-Datei in einem Browser und schauen Sie sich die Konsole an.

Gewöhnen Sie sich an, Ihren Code mit diesen Zeilen zu umgeben:

$(document).ready(function(){
  ...
});

So stellen Sie sicher, dass Ihr Code erst ausgeführt wird, wenn die Seite geladen ist.

(E2) Modaldialog in jQuery

Schauen Sie sich das Beispiel "Modales Dialogfenster" im Kapitel 9.4. JavaScript im Web an.

Laden Sie sich den Code runter und ersetzen Sie - wo möglich - die JavaScript-Befehle durch jQuery-Mechanismen:

Modales Dialogfenster (JS) →

Tipp: Denken Sie daran, dass eventuell ein # oder . beim Selektieren fehlt, wenn Sie auf jQuery umsteigen.

Folgeaufgabe: Wenn wir schon in jQuery sind, können Sie Übergänge hinzufügen. Nutzen Sie z. B. fadeIn, um die halbtransparente graue Fläche langsam einzublenden.

10.6.2 Manipulation des DOM

Die folgenden Aufgaben beziehen sich auf diesen Basiscode:

Headlines →

Sie sehen Überschriften und Texte:

Seite mit Überschriften

In der Datei finden Sie bereits eine Verlinkung mit einer jQuery-Bibliothek und einen Code-Bereich (<script>) für Sie.

(M1) Absätze einfärben

Nehmen Sie den Basiscode:

Headlines →

Implementieren Sie folgenden Mouseover-Effekte.

(a) Zunächst ein leichter Effekt: Wenn Sie mit der Maus einen Absatz berühren, soll dieser mit gelb unterlegt werden.

(b) Erweitern Sie dies, so dass sowohl Absätze als auch alle Überschriften sich so verhalten.

(c) Ein ganz anderer Ansatz: Wenn Sie mit der Maus eine Überschrift berühren, sollen alle darunter liegenden Absätze gelb eingefärbt werden (nur Absätze, keine Überschriften).

(M2) Überschriften nummerieren

Nehmen Sie wieder den Basiscode:

Headlines →

Hier haben wir zwei Teile:

(a) Schreiben Sie jQuery-Code, der alle h2-Überschriften mit einer Nummerierung versieht:

Seite mit nummerierten Überschriften

Sie benötigen die jQuery-Methode text, um den Text zu modifizieren, und offensichtlich müssen Sie die Überschriften "zählen".

(b) Anschließend versuchen Sie, die nächste Ebene zu nummerieren:

Seite mit nummerierten Unterüberschriften

(M3) Automatisches Inhaltsverzeichnis

Nehmen Sie den folgenden Basiscode:

TOC →

Erstellen Sie automatisch ein Inhaltsverzeichnis (engl. table of contents) in Form einer Liste. Dazu sammeln Sie alle Überschriften vom Typ h2 und h3 ein und erzeugen eine entsprechende Liste. Binden Sie das ganze als nav-Element in Ihr Dokument ein.

Außerdem sollten Sie seiteninterne Links mit IDs erzeugen. Diese IDs sollte Ihr Code nach einem eigenen System erzeugen.

Ihr Dokument soll bei Erfolg so aussehen:

Dokument mit Inhaltsverzeichnis

10.6.3 Interaktion

(I1) Elemente nach Tags filtern

Es sei eine Webseite mit Boxen gegeben. Diese Boxen haben Schlagworte oder Tags. Sie sollen eine Reihe von Filter-Buttons generieren, so dass auf Knopfdruck nur die Boxen bleiben, die diese Tags aufweisen.

Seite mit Filterleiste

Nach Drücken auf "cat" zeigt sich dieses Bild:

Seite mit Filterleiste: gefiltert nach cat

Verwenden Sie den folgenden Basiscode und fügen Sie jQuery-Code hinzu:

Aufgabe Tags (jQ) →

Bei den Boxen sehen Sie folgende Attribute:

<div class="box" data-tags="panda,big">
  panda,big
</div>

Die Schreibweise beim Attribut "data-tags" erlaubt ein besonders elegantes Auslesen des Attributs in JavaScript. Wenn die Variable bx eine solche Box enthält, greifen Sie so auf das Attribut data-tags zu:

bx.dataset.tags

Siehe auch Using data attributes .

Tipps: