Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JavaScript

Erstellen Sie das perfekte Karussell, Teil 3

by
Read Time:12 minsLanguages:
This post is part of a series called Create the Perfect Carousel.
Create the Perfect Carousel, Part 2

German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)

Dies ist der dritte und letzte Teil unserer Tutorial-Reihe "Create the Perfect Carousel". In Teil 1 haben wir die Karussells auf Netflix und Amazon bewertet, zwei der am häufigsten verwendeten Karussells der Welt. Wir haben unser Karussell eingerichtet und Touch Scroll implementiert.

Dann haben wir in Teil 2 eine horizontale Mausrolle, eine Paginierung und eine Fortschrittsanzeige hinzugefügt. Boom.

In unserem letzten Teil werden wir uns nun mit der trüben und oft vergessenen Welt der Tastaturzugänglichkeit befassen. Wir passen unseren Code an, um das Karussell erneut zu messen, wenn sich die Größe des Ansichtsfensters ändert. Und zum Schluss noch ein paar Feinarbeiten mit der Frühlingsphysik.

Mit diesem CodePen können Sie dort weitermachen, wo wir aufgehört haben.

Tastaturzugriff

Es ist wahr, dass sich die Mehrheit der Benutzer nicht auf die Tastaturnavigation verlässt. Leider vergessen wir manchmal unsere Benutzer, die dies tun. In einigen Ländern kann es illegal sein, eine Website unzugänglich zu lassen. Aber schlimmer noch, es ist eine Schwanzbewegung.

Die gute Nachricht ist, dass es normalerweise einfach zu implementieren ist! In der Tat erledigen Browser den größten Teil der Arbeit für uns. Im Ernst: Versuchen Sie, durch das Karussell zu tippen, das wir gemacht haben. Da wir semantisches Markup verwendet haben, können Sie dies bereits!

Außer, Sie werden feststellen, dass unsere Navigationsschaltflächen verschwinden. Dies liegt daran, dass der Browser keinen Fokus auf ein Element außerhalb unseres Ansichtsfensters zulässt. Obwohl wir overflow: hidden Menge haben, können wir die Seite nicht horizontal scrollen; andernfalls wird die Seite tatsächlich gescrollt, um das Element mit Fokus anzuzeigen.

Dies ist in Ordnung und würde meiner Meinung nach als "wartungsfähig" gelten, wenn auch nicht gerade erfreulich.

Das Karussell von Netflix funktioniert ebenfalls auf diese Weise. Da die meisten ihrer Titel jedoch faul geladen sind und auch passiv über die Tastatur zugänglich sind (dh sie haben keinen Code speziell dafür geschrieben), können wir keine Titel auswählen, die über die wenigen hinausgehen, die wir haben bereits geladen. Es sieht auch schrecklich aus:

Keyboard AccessibilityKeyboard AccessibilityKeyboard Accessibility

Wir können es besser machen.

Behandeln Sie das fokus-Ereignis

Zu diesem Zweck hören wir uns das fokus-Ereignis an, das auf ein Element im Karussell ausgelöst wird. Wenn ein Objekt den Fokus erhält, werden wir es nach seiner Position abfragen. Anschließend überprüfen wir dies anhand von sliderX und sliderVisibleWidth, um festzustellen, ob sich das Element im sichtbaren Fenster befindet. Wenn dies nicht der Fall ist, werden wir mit demselben Code paginieren, den wir in Teil 2 geschrieben haben.

Fügen Sie am Ende der carousel-Funktion diesen Ereignis-Listener hinzu:

Sie werden feststellen, dass wir einen dritten Parameter angegeben haben, true. Anstatt jedem Element einen Ereignis-Listener hinzuzufügen, können wir die so genannte Ereignisdelegation verwenden, um Ereignisse auf nur einem Element, dem direkten übergeordneten Element, abzuhören. Das fokus-Ereignis sprudelt nicht, so dass der Ereignis-Listener true angewiesen wird, auf die capture-Phase zu warten, die Phase, in der das Ereignis auf jedes Element von window bis zum Ziel (in diesem Fall das Element, das den Fokus erhält) ausgelöst wird.

Fügen Sie über unserem wachsenden Block von Ereignis-Listenern die onFocus-Funktion hinzu:

Wir werden in dieser Funktion für den Rest dieses Abschnitts arbeiten.

Wir müssen den left und right Versatz des Elements messen und prüfen, ob einer der Punkte außerhalb des aktuell sichtbaren Bereichs liegt.

Das Element wird vom target-Parameter des Ereignisses bereitgestellt, und wir können es mit getBoundingClientRect messen:

left und right beziehen sich auf das Ansichtsfenster, nicht auf den Schieberegler. Um dies zu berücksichtigen, müssen wir den left Versatz des Karussellcontainers berücksichtigen. In unserem Beispiel ist dies 0, aber um das Karussell robust zu machen, sollte es berücksichtigt werden, dass es irgendwo platziert wird.

Jetzt können wir eine einfache Überprüfung durchführen, um festzustellen, ob sich das Element außerhalb des sichtbaren Bereichs des Schiebereglers befindet, und in diese Richtung paginieren:

Wenn wir uns jetzt umsehen, paginiert das Karussell souverän mit unserem Tastaturfokus! Nur ein paar Zeilen Code, um unseren Benutzern mehr Liebe zu zeigen.

Karussell erneut messen

Möglicherweise haben Sie beim Befolgen dieses Tutorials bemerkt, dass das Karussell nicht mehr richtig paginiert, wenn Sie die Größe Ihres Browser-Ansichtsfensters ändern. Dies liegt daran, dass wir seine Breite relativ zu seinem sichtbaren Bereich zum Zeitpunkt der Initialisierung nur einmal gemessen haben.

Um sicherzustellen, dass sich unser Karussell korrekt verhält, müssen wir einen Teil unseres Messcodes durch einen neuen Ereignis-Listener ersetzen, der ausgelöst wird, wenn die window-Größe geändert wird.

Kurz vor dem Start Ihrer carousel-Funktion, kurz nach der Zeile, in der wir progressBar definieren, möchten wir drei dieser const Messungen durch let ersetzen, da wir sie ändern werden, wenn sich das Ansichtsfenster ändert:

Dann können wir die Logik, die diese Werte zuvor berechnet hat, in eine neue measureCarousel-Funktion verschieben:

Wir möchten diese Funktion sofort aufrufen, damit wir diese Werte bei der Initialisierung weiterhin festlegen. Rufen Sie in der nächsten Zeile measureCarousel auf:

Das Karussell sollte genauso funktionieren wie zuvor. Um die Fenstergröße zu aktualisieren, fügen wir diesen Ereignis-Listener einfach ganz am Ende unserer carousel-Funktion hinzu:

Wenn Sie nun die Größe des Karussells ändern und versuchen, es zu paginieren, funktioniert es weiterhin wie erwartet.

Ein Hinweis zur Leistung

In der realen Welt befinden sich möglicherweise mehrere Karussells auf derselben Seite, wobei die Auswirkungen dieses Messcodes auf die Leistung mit diesem Betrag multipliziert werden.

Wie wir in Teil 2 kurz besprochen haben, ist es unklug, öfter schwere Berechnungen durchzuführen, als Sie müssen. Bei Zeiger- und Bildlaufereignissen haben wir gesagt, dass Sie diese einmal pro Frame ausführen möchten, um 60 fps aufrechtzuerhalten. Größenänderungsereignisse unterscheiden sich geringfügig darin, dass das gesamte Dokument erneut ausgeführt wird. Dies ist wahrscheinlich der ressourcenintensivste Moment, in dem eine Webseite auftritt.

Wir müssen das Karussell nicht erneut messen, bis der Benutzer die Größe des Fensters geändert hat, da er in der Zwischenzeit nicht mit ihm interagiert. Wir können unsere MeasureCarousel-Funktion in eine spezielle Funktion einbinden, die als debounce bezeichnet wird.

Eine Entprellungsfunktion sagt im Wesentlichen: "Diese Funktion wird nur ausgelöst, wenn sie nicht länger als x Millisekunden aufgerufen wurde." Sie können mehr über das Entprellen von David Walshs ausgezeichnetem Primer lesen und auch einen Beispielcode aufgreifen.

Feinschliff

Bisher haben wir ein ziemlich gutes Karussell erstellt. Es ist zugänglich, animiert gut, funktioniert über Touch und Maus und bietet ein hohes Maß an Designflexibilität auf eine Weise, die das native Scrollen von Karussells nicht zulässt.

Dies ist jedoch nicht die Tutorialserie "Create a Pretty Good Carousel". Es ist Zeit für uns, ein wenig anzugeben, und dazu haben wir eine Geheimwaffe. Federn.

Wir werden zwei Interaktionen mit Federn hinzufügen. Eine zur Berührung und eine zur Paginierung. Beide werden den Benutzer auf unterhaltsame und spielerische Weise darüber informieren, dass sie das Ende des Karussells erreicht haben.

Berühren Sie Feder 

Fügen wir zunächst einen Schlepper im iOS-Stil hinzu, wenn ein Benutzer versucht, den Schieberegler über seine Grenzen hinaus zu scrollen. Derzeit wird der Touch-Scroll mit clampXOffset begrenzt. Ersetzen wir dies stattdessen durch einen Code, der einen Schlepper anwendet, wenn der berechnete Versatz außerhalb seiner Grenzen liegt.

Zuerst müssen wir unseren Feder importieren. Es gibt einen Transformator namens nonlinearSpring, der eine exponentiell ansteigende Kraft gegen die von uns bereitgestellte Zahl auf einen origin ausübt. Das heißt, je weiter wir den Schieber ziehen, desto mehr zieht er sich zurück. Wir können es so importieren:

In der Funktion determinDragDirection haben wir diesen Code:

Lassen Sie uns direkt darüber unsere zwei Federn erstellen, eine für jede Bildlaufbegrenzung des Karussells:

Die Entscheidung für einen Wert für elasticity ist eine Frage des Herumspielens und des Sehens, was sich richtig anfühlt. Eine zu niedrige Zahl, und die Feder fühlt sich zu steif an. Zu hoch und Sie werden das Ziehen nicht bemerken, oder schlimmer noch, es wird den Schieber noch weiter vom Finger des Benutzers wegdrücken!

Jetzt müssen wir nur noch eine einfache Funktion schreiben, die eine dieser Federn anwendet, wenn der angegebene Wert außerhalb des zulässigen Bereichs liegt:

Wir können clampXOffset im obigen Code durch applySpring ersetzen. Wenn Sie den Schieberegler über seine Grenzen hinaus ziehen, wird er zurückgezogen!

Wenn wir jedoch den Frühling loslassen, rastet er kurzerhand wieder ein. Wir möchten unsere stopTouchScroll-Funktion ändern, die derzeit das Momentum-Scrollen übernimmt, um zu überprüfen, ob sich der Schieberegler noch außerhalb des zulässigen Bereichs befindet, und in diesem Fall stattdessen eine Feder mit der physics-Aktion anwenden.

Frühlingsphysik

Die physics Aktion kann auch Federn modellieren. Wir müssen es nur mit spring- und to- Eigenschaften versehen.

Verschieben Sie in stopTouchScroll die vorhandene Initialisierung der Bildlauf-physics in eine Logik, die sicherstellt, dass wir uns innerhalb der Bildlaufgrenzen befinden:

In der ersten Klausel der if-Anweisung wissen wir, dass sich der Schieberegler außerhalb der Bildlaufgrenzen befindet, sodass wir unsere Feder hinzufügen können:

Wir wollen eine Feder schaffen, die sich bissig und reaktionsschnell anfühlt. Ich habe einen relativ hohen spring-Wert gewählt, um einen engen "Knall" zu erzielen, und ich habe friction auf 0.92 gesenkt, um ein wenig Sprungkraft zu ermöglichen. Sie können dies auf 1 setzen, um den Sprung vollständig zu eliminieren.

Versuchen Sie als Hausaufgabe, das clampXOffset in der output-Funktion der Scroll-physics durch eine Funktion zu ersetzen, die eine ähnliche Feder auslöst, wenn der x-Offset seine Grenzen erreicht. Versuchen Sie, den aktuellen abrupten Stopp am Ende sanft abprallen zu lassen.

Paginierungsfrühling

Touch-Benutzer bekommen immer die Frühlingsgüte, oder? Lassen Sie uns diese Liebe den Desktop-Benutzern mitteilen, indem wir feststellen, wann das Karussell an seinen Bildlaufgrenzen stößt, und einen indikativen Ruck verwenden, um dem Benutzer klar und sicher zu zeigen, dass sie am Ende sind.

Zunächst möchten wir die Paginierungsschaltflächen deaktivieren, wenn das Limit erreicht ist. Fügen wir zunächst eine CSS-Regel hinzu, die die Schaltflächen so formatiert, dass sie disabled sind. Fügen Sie in der button-Regel Folgendes hinzu:

Wir verwenden hier eine Klasse anstelle des semantisch disabled-Attributs, da wir weiterhin Klickereignisse erfassen möchten, die, wie der Name schon sagt, disabled blockieren würden.

Fügen Sie diese disabled Klasse zur Schaltfläche Zurück hinzu, da jedes Karussell mit einem 0-Offset beginnt:

Erstellen Sie oben in carousel eine neue Funktion namens checkNavButtonStatus. Wir möchten, dass diese Funktion einfach den angegebenen Wert mit minXOffset und maxXOffset vergleicht und die Klasse für disabled Schaltflächen entsprechend festlegt:

Es wäre verlockend, dies jedes Mal aufzurufen, wenn sich sliderX ändert. In diesem Fall blinken die Tasten immer dann, wenn eine Feder um die Bildlaufgrenzen schwingt. Es würde auch zu seltsamem Verhalten führen, wenn eine der Tasten während einer dieser Frühlingsanimationen gedrückt würde. Der Schlepper "Scroll End" sollte immer ausgelöst werden, wenn wir uns am Ende des Karussells befinden, auch wenn eine Frühlingsanimation ihn vom absoluten Ende wegzieht.

Wir müssen also selektiver entscheiden, wann diese Funktion aufgerufen werden soll. Es scheint vernünftig, es zu nennen:

Fügen Sie in der letzten Zeile des onWheel checkNavButtonStatus(newX); hinzu.

Fügen Sie in der letzten Zeile von goto checkNavButtonStatus(targetX); hinzu.

Und schließlich ersetzen Sie am Ende von determinDragDirection und in der Momentum-Scroll-Klausel (dem Code im else) von stopTouchScroll:

Mit:

Jetzt müssen Sie nur noch gotoPrev und gotoNext ändern, um die Klassenliste der Auslöseschaltfläche auf disabled zu überprüfen und nur dann zu paginieren, wenn sie nicht vorhanden ist:

Die notifyEnd-Funktion ist nur eine weitere physics-Quelle und sieht folgendermaßen aus:

Spielen Sie damit und passen Sie die physics-Parameter wieder nach Ihren Wünschen an.

Es gibt nur noch einen kleinen Fehler. Wenn der Schieberegler über die äußerste linke Grenze hinaus springt, wird der Fortschrittsbalken invertiert. Wir können das schnell beheben, indem wir Folgendes ersetzen:

Mit:

Wir könnten verhindern, dass es in die andere Richtung springt, aber ich persönlich finde es ziemlich cool, dass es die Federbewegung widerspiegelt. Es sieht nur seltsam aus, wenn es von innen nach außen dreht.

Räumen Sie nach sich selbst auf

Bei einseitigen Anwendungen halten Websites in der Sitzung eines Benutzers länger. Selbst wenn sich die "Seite" ändert, wird häufig immer noch dieselbe JS-Laufzeit ausgeführt wie beim ersten Laden. Wir können uns nicht jedes Mal auf eine saubere Tafel verlassen, wenn der Benutzer auf einen Link klickt. Das bedeutet, dass wir nach uns selbst aufräumen müssen, um zu verhindern, dass Ereignis-Listener auf tote Elemente schießen.

In React wird dieser Code in die componentWillLeave-Methode eingefügt. Vue verwendet beforeDestroy. Dies ist eine reine JS-Implementierung, aber wir können immer noch eine Zerstörungsmethode bereitstellen, die in beiden Frameworks gleichermaßen funktioniert.

Bisher hat unsere carousel-Funktion nichts zurückgegeben. Lassen Sie uns das ändern.

Ändern Sie zunächst die letzte Zeile, die carousel aufruft, in:

Wir werden nur eine Sache aus carousel zurückgeben, eine Funktion, die alle unsere Event-Zuhörer auflöst. Schreiben Sie ganz am Ende der carousel-Funktion:

Wenn Sie jetzt destroyCarousel aufrufen und versuchen, mit dem Karussell zu spielen, passiert nichts! Es ist fast ein bisschen traurig, das so zu sehen.

Und das ist das

Wütend. Das war viel! Wie weit wir gekommen sind. Sie können das fertige Produkt an diesem CodePen sehen. In diesem letzten Teil haben wir die Tastaturzugänglichkeit hinzugefügt, das Karussell neu gemessen, wenn sich das Ansichtsfenster ändert, einige lustige Ergänzungen mit der Frühlingsphysik und den herzzerreißenden, aber notwendigen Schritt, alles wieder abzureißen.

Ich hoffe, Ihnen hat dieses Tutorial genauso gut gefallen wie mir das Schreiben. Ich würde gerne Ihre Gedanken darüber hören, wie wir die Zugänglichkeit verbessern oder mehr lustige kleine Details hinzufügen können.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.