Nur eines dieser Dinge, die man über JavaScript verstehen muss

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Seitdem ich den Artikel Dynamic Page / Replacing Content veröffentlicht habe, erhalte ich viele E-Mails von Leuten, die versuchen, ihn in Verbindung mit anderen JavaScript-Funktionen zu verwenden und dabei Schwierigkeiten haben. Meistens handelt es sich um eine Art Lightbox-Effekt. Eine ihrer Seiten enthält eine Reihe von Thumbnails, und wenn sie diese Seite laden, funktioniert der Lightbox-Effekt nicht.

Das Problem ist, dass die Thumbnails, wenn sie auf die Seite geladen werden (per Ajax, d. h. mit der .load()-Funktion von jQuery), keine Ereignisse an sich gebunden haben.

/* Your lightbox plugin */
$("photos a").ceebox();  

/* Basics of Ajax */
$("nav a").click(function(e) {
    e.preventDefault();
    $("#main-content").load(this.href);  /* Thumbnails loaded from here */
});

Die Funktionsweise des Lightbox-Plugins (wahrscheinlich) besteht darin, dass es beim Laden der Seite Klick-Ereignisse an die Elemente bindet, die Sie als Selektor übergeben haben (die Thumbnails), und diese Klick-Ereignisse führen die Lightbox-Aktion aus. Da die neu geladenen Thumbnails keinen Klick-Event haben, funktioniert die Lightbox-Aktion nicht.

Eine Möglichkeit, dies zu beheben, ist, das Lightbox-Plugin nach dem Laden des Inhalts aufzurufen, in der Callback-Funktion der load-Funktion.

$("photos a").ceebox();  

$("nav a").click(function(e) {
    e.preventDefault();
    $("#main-content").load(this.href, function() {

              /* Callback function */
              $("photos a").ceebox();  /* Call this again */

    });
});

Ein wenig repetitiv, aber das erledigt die Aufgabe.

Ein besserer Weg mit Delegate

Obwohl dies "einfach die Funktionsweise von JavaScript" ist, ist es ein bekannter Schmerzpunkt. Da jQuery eine Bibliothek ist, die existiert, um solche Probleme zu lindern, hat sie natürlich einen besseren Weg. Dieser Weg ist die Funktion .delegate(), bei der Sie anstatt Ereignisse an einzelne Elemente zu binden, ein Ereignis an ein Element höher im DOM-Baum binden, das wahrscheinlich nicht per Ajax ersetzt wird, und das auf diese Klicks achtet.

Dies beruht auf etwas, das als Event Bubbling bekannt ist, ein nettes und wichtiges Konzept in JavaScript (wirklich: das DOM-Modell). Wenn Sie auf ein Thumbnail klicken, wird ein Klick-Ereignis für dieses Element ausgelöst, dann ein Klick-Ereignis für sein übergeordnetes Element und ein Klick-Ereignis für das übergeordnete Element seines übergeordneten Elements, bis hin zum Wurzelelement. Aus diesem Grund können wir von höheren Elementen aus auf Klicks auf tiefere Elemente warten.

Leider müssten Sie in unserem Lightbox-Beispiel das Plugin selbst ändern, um es dazu zu bringen, Delegate anstelle der direkten Bindung an die Elemente zu verwenden. Das ist definitiv machbar, aber schwieriger, da Sie wahrscheinlich nicht so gut mit dem Code dieses Plugins vertraut sind wie mit Ihrem eigenen.

Hören Sie auf Remy Sharp

Während dieser Artikel entworfen wurde, veröffentlichte Remy Sharp einen Video-Screencast zu genau diesem Thema. Er kann es viel besser erklären als ich, also schauen Sie sich das unbedingt an.