Erstellen Sie ein ansprechendes Javascript-Navigationsmenü

Sich anpassendes Webdesign (RWD) hat einen enormen Einfluss darauf gehabt, wie unsere Branche Websites und Anwendungen für verschiedene Geräte entwickelt. Überall, wo wir hinschauen, gibt es neue Techniken, Werkzeuge und Gedanken zu diesem Thema. RWD bietet uns die Tools, die wir benötigen, um großartige Erlebnisse für die Vielzahl von Geräten zu schaffen, über die unsere Benutzer verfügen.

Ethan Marcottes Originalartikel skizziert die drei Kernelemente eines reaktionsschnellen Designs: flüssige Gitter, flexible Bilder und Medienabfragen. JavaScript ist zwar keine dieser Grundlagen von RWD, ermöglicht Entwicklern jedoch, die Interaktionen zu verbessern und den Benutzern umfassendere Erfahrungen zu bieten. Viele Leute (ich selbst eingeschlossen) würden argumentieren, dass unser Inhalt Benutzern ohne aktiviertes JavaScript zur Verfügung stehen sollte. Hier gehen wir eine feine Linie zwischen der Verwendung von JavaScript, um unsere Websites benutzerfreundlicher zu machen, und dem Verstecken von Inhalten hinter einer JS-Wand.

  • Bekommen das Quelldaten für dieses Tutorial

Wenn Sie Zeit damit verbringen, JavaScript für RWD zu schreiben, werden Sie sicher auf die Arbeit von stoßen Scott Jehl des Filamentgruppe . Es ist ein Glück für uns, dass es solche Leute gibt, die Tools erstellen und teilen, um Responsive Design voranzutreiben.



Lass uns etwas bauen

Ich habe keine genaue Aufschlüsselung, wie viel Zeit wir in den einzelnen Abschnitten unserer Websites verbringen, aber wir widmen uns im Allgemeinen mehr der Navigation (insbesondere für große Websites) als jedem anderen Aspekt. Sicherzustellen, dass wir die richtigen Inhalte haben, dass sie gut organisiert sind, leicht zu erreichen sind, zugänglich sind und Funktionen auf allen Geräten, die wir in die Hände bekommen können, gelinde gesagt zeitaufwändig sein können.

Verwenden Sie jQuery, um Browserinkonsistenzen mit Ereignisbindungen einfach zu behandeln und das Umschalten von Klassen für DOM-Elemente zu vereinfachen

Verwenden Sie jQuery, um Browserinkonsistenzen mit Ereignisbindungen einfach zu behandeln und das Umschalten von Klassen für DOM-Elemente zu vereinfachen

Um unser Leben zu vereinfachen, bauen wir eine reaktionsschnelle Navigation auf. Einige Ziele für diese Navigation sind:

  1. Gute Arbeit auf kleinen und großen Bildschirmen.
  2. Um in Chrome, Safari, Firefox und IE (8+) zu arbeiten.
  3. Mit oder ohne JavaScript arbeiten.

Das Markup

Wenn Sie die Dateien aus dem Lernprogramm nicht verwenden, ist jetzt ein guter Zeitpunkt, um zumindest zu kopieren base.css . Da wir uns hier auf JavaScript konzentrieren, werden wir uns nicht viel mit CSS befassen. Nehmen Sie die Datei index.html zur Hand aus den Tutorial-Dateien und fangen wir an.

Wenn Sie sich den HTML-Code angesehen haben, fragen Sie sich möglicherweise: Warum befindet sich das Navi in ​​der Fußzeile? Gute Frage. Eines unserer Ziele war es, die Navigation Nicht-JavaScript-Benutzern zur Verfügung zu stellen. Für Benutzer auf kleinen Bildschirmen ohne JS möchten wir nicht, dass das Navigationsgerät den Bildschirm auffrisst, wenn sie die Seite besuchen. In der Kopfzeile haben wir also einen Link zur Navigation, die in der Fußzeile vorhanden (erweitert) ist.

Die Navigation in kleiner Größe nach Berühren / Klicken auf das Menüsymbol, um das Off-Canvas-Element anzuzeigen

Die Navigation in kleiner Größe nach Berühren / Klicken auf das Menüsymbol, um das Off-Canvas-Element anzuzeigen

Kleinste zuerst

Es ist im Allgemeinen viel einfacher, reaktionsfähige Websites zu erstellen, wenn Sie mit der kleinsten Größe beginnen und von dort aus arbeiten. Zu diesem Zeitpunkt sollten Sie eine Navigation haben, die bei kleinem Format mit deaktiviertem JavaScript funktioniert Nav anzeigen Link (der derzeit nichts tut) in dieser Größe, wenn JavaScript aktiviert ist, und funktioniert mit einem einfachen Hover bei großen Größen sowohl mit als auch ohne JavaScript.

Beginnen wir mit dem Hinzufügen von JavaScript, um der kleinen Navigation ein wenig Leben einzuhauchen. Sie müssen Verweise auf jQuery und das Navigations-JavaScript unmittelbar vor dem schließenden Body-Tag von hinzufügen index.html .

Wir werden mit dem Folgenden beginnen nav.js . Dadurch wird ein Objekt erstellt ( window.NAV ) um den gesamten Code zur Steuerung unserer Navigation zu enthalten:

(function() { window.NAV = { $body: $('body'), $subMenus: $('.subMenu'), toggle: function(e) { e.preventDefault(); NAV.$body.toggleClass('mainMenu-is-open'); }, bindEvents: function() { $('.js-togglesOffCanvas').on('click', NAV.toggle); }, init: function() { NAV.bindEvents(); } } })(); NAV.init();

Das drin Die obige Methode enthält alle erforderlichen Einstellungen. Hier ruft es an NAV.bindEvents , die jQuery verwendet, um ein Klickereignis an etwas mit einer Klasse von zu binden js-togglesOffCanvas , um die NAV.toggle-Methode .

NAV.toggle wird verhindern, dass das Standardereignis ausgelöst wird (wir folgen also nicht den Links, die wir nicht wollen) und jQuery verwenden, um das zu ändern mainMenu-is-open Klasse am Körper. Dadurch werden die CSS-Regeln zum Verschieben der .mainNav div (derzeit auf der linken Seite des Bildschirms positioniert) wird mithilfe von CSS-Transformationen angezeigt. Verwenden von translate3d Erzwingt die Hardwarebeschleunigung in WebKit. So können wir erkennen, was mit verfügbar ist Modernizr und verwenden translate3d (falls verfügbar) für flüssigere Animationen.

Hervorheben des Overlay-Div über JavaScript. Das Klickereignis auf diesem Div ist an die Aktion zum Schließen des Menüs gebunden

Hervorheben des Overlay-Div über JavaScript. Das Klickereignis auf diesem Div ist an die Aktion zum Schließen des Menüs gebunden

Da unsere Veranstaltung an die Klasse gebunden ist js-togglesOffCanvas müssen Sie diese Klasse zum Show-Link in der Kopfzeile hinzufügen:

Show Nav

Sie sollten jetzt eine Navigation haben, die von links in einer kleinen Größe eingeblendet wird, wenn Sie auf klicken Nav anzeigen Verknüpfung. Aber warten Sie - wir haben keine Möglichkeit, die Navigation zu schließen, nachdem wir sie geöffnet haben. Lassen Sie uns das beheben.

Ich hätte gerne einen Button oben links an der Stelle, an der sich der offene Link befand, bevor wir ihn nach rechts schoben. Ich möchte auch in der Lage sein, auf etwas rechts neben der Navigation zu klicken, um ein Schließen auszulösen. Anstatt zu versuchen, einen Ereignis-Listener zu allem auf der rechten Seite hinzuzufügen, lassen Sie uns ein Overlay-Div einfügen und auf Klicks warten. Erstellen Sie eine JS-Variable, um das Markup zu speichern und unserem NAV-Objekt hinzuzufügen:

window.NAV = { $clickOverlay: $(' '), …

Wir werden dann eine Zeile zum hinzufügen drin Methode zum Hinzufügen dieses Div zum DOM. Auf diese Weise fügen wir dies nur hinzu, wenn wir JS haben und das Off-Canvas-Navi möglicherweise aktiviert ist.

MacBook Pro 15 Zoll Schutzhülle
init: function() { NAV.$clickOverlay.appendTo('body'); NAV.bindEvents(); }

Wenn Sie dieses div sehen möchten, fügen Sie eine Klasse von hinzu sichtbar: Da dieses Element unsichtbar ist, kann dies zum Testen hilfreich sein. Jetzt ist ein guter Zeitpunkt, um die Schaltfläche zum Schließen dem Navigationsgerät selbst hinzuzufügen. Füge hinzu ein nur innerhalb von ::

Close Menu

Jetzt können wir unsere Navigation schließen - eine Erleichterung - obwohl wir in diesem Off-Canvas-Zustand nicht zu den Links der zweiten Ebene gelangen können. Wir können etwas dagegen tun, indem wir einige Änderungen an unserem vornehmen nav.js Datei. Fügen Sie diese Methode zunächst dem hinzu SIND NICHT Objekt:

toggleSubNav: function(e) { e.preventDefault(); $(this).siblings('ul').stop().slideToggle('fast'); },

Fügen Sie als Nächstes einen Klick-Handler für hinzu .js-togglesSubMenu zu NAV.bindEvents .

bindEvents: function() { $('.js-togglesOffCanvas').on('click', NAV.toggle); $('.mainNav').on('click', '.js-togglesSubMenu', NAV.toggleSubNav); },

Ergänzen Sie die js-togglesSubMenu Klasse zu jedem Link, der ein Untermenü öffnen soll

    im index.html .

  • Products

    Diese Navigation kommt jetzt wirklich zusammen, aber wenn Sie herumspielen, können Sie ein paar Probleme finden. Das erste wird angezeigt, wenn das Navi außerhalb der Leinwand geöffnet ist und eine Änderung der Medienabfrage bewirkt, dass das Layout zum Layout außerhalb der Leinwand wechselt. Alles sieht kaputt aus: die Körper Element hat noch eine Klasse von mainMenu-is-open angewendet. Wenn Sie ein Untermenü öffnen und dann schließen, funktioniert der Hover-Effekt bei der größeren Größe nicht - ein Problem, wenn der Haltepunkt, an dem dieser Wechsel erfolgt, zwischen dem Hoch- und Querformat eines Handheld-Geräts liegt.

    Die Off-Canvas-Navigation wurde geöffnet und vollständig erweitert, um ein Menü der zweiten Ebene anzuzeigen

    Die Off-Canvas-Navigation wurde geöffnet und vollständig erweitert, um ein Menü der zweiten Ebene anzuzeigen

    Derzeit lösen Browser keine Ereignisse aus, wenn Medienabfragen den Status ändern. Neuere Browser haben jedoch Zugriff darauf, zu bestimmen, ob eine bestimmte Medienabfrage über das angewendet wird matchMedia API . In diesem Fall verwende ich einen Wrapper. mediaCheck , die ich um die matchMedia API geschrieben habe. Damit können wir Funktionen einrichten, die ausgeführt werden, wenn eine Medienabfrage aktiv wird oder nicht mehr aktiv ist. Dazu fügen wir kurz zuvor in index.html einen Verweis auf mediaCheck hinzu nav.js ::

    Als nächstes müssen wir den Code hinzufügen, um zu sagen mediaCheck welche Medienabfragen zu sehen sind und was zu tun ist, wenn sie sich ändern. Fügen Sie diese Zeilen am Ende von init hinzu Funktion() .

    mediaCheck({ media: '(min-width: 35em)', entry: function() { NAV.clear(); } });

    Fügen Sie nun die hinzu NAV.clear Methode. Entferne das mainMenu-is-open Klasse aus dem Körper entfernen, Elemente zurücksetzen, die verschoben wurden, damit das Navigationsgerät wieder an die richtigen Stellen zurückkehrt, und Inline-Stile entfernen, die den Elementen hinzugefügt wurden: jQuery-Animationen:

    window.NAV = { $subMenus: $('.subMenu'), clear: function() { NAV.$body.removeClass('mainMenu-is-open'); NAV.$subMenus.removeAttr('style'); } …

    Immer wenn die Browserbreite größer oder gleich 35ems wird, wird die mainMenu-is-open Klasse und die Inline-Stile aus jQuery werden entfernt.

    Geräte im Uhrzeigersinn von oben links: das Apple iPad, das BlackBerry Z10 und Apple

    Geräte im Uhrzeigersinn von oben links: das Apple iPad, das BlackBerry Z10 und das Apple iPhone 5

    Ein weiteres Problem besteht darin, dass die Übergänge, die die gleitende Animation außerhalb der Leinwand erstellen, weiterhin angewendet werden, wenn das Navigationssystem zwischen Kontexten wechselt. Dies führt zu einer ziemlich hässlichen Verschiebung zwischen Medienabfragen. Wir können auf dem Fix für das erste Problem aufbauen, indem wir die folgende Methode hinzufügen window.NAV ::

    toggleAnimations: function() { if ( APP.getState() === 'small' ) { NAV.$body.addClass('enableAnimations'); } else { NAV.$body.removeClass('enableAnimations'); } },

    Modifiziere den mediaCheck Rufen Sie die init-Methode wie folgt auf:

    mediaCheck({ media: '(min-width: 30em)', entry: function() { NAV.clear(); NAV.toggleAnimations(); }, exit: function() { NAV.toggleAnimations(); } });

    Und schließlich ändern Sie Zeile 80 von base.css sein:

    .enableAnimations .mainNav, .enableAnimations .mainContent, .enableAnimations .masthead, .enableAnimations .clickOverlay {

    Jetzt sind die Übergänge an die gebunden enableAnimations Klasse vorhanden ist, und diese Klasse wird nur bei der kleinen Größe angewendet.

    Sie werden das dritte Problem bemerken, wenn Sie versuchen, auf das Produktmenü in der größeren Größe zu klicken. Das Anzeigen des Navis der zweiten Ebene in dieser Größe sollte vom Schwebeflug ausgeführt werden. Der Klick-Handler, den wir angewendet haben, um mit der kleineren Größe umzugehen, wird immer noch ausgelöst.

    Mit Modernizr können wir mithilfe der Feature-Erkennung CSS- und JavaScript-Entscheidungen treffen

    Mit Modernizr können wir mithilfe der Feature-Erkennung CSS- und JavaScript-Entscheidungen treffen

    Das ist etwas kniffliger. Ich habe ursprünglich eine Lösung entwickelt, aber mit Hilfe von Adam Simpson haben große Verbesserungen gemacht. Ansehen app.js. In den Tutorial-Dateien sehen Sie eine Methodendefinition für APP.getState , die ein Element mit einer ID von injiziert SizeTest in die Seite. Dieses Element greift Stile aus dem CSS auf, um eine Vorstellung davon zu erhalten, welche Größe der Browser im Verhältnis zu den definierten Medienabfragen hat. Ergänzen Sie die app.js. Verweis auf index.html:

    Im CSS finden Sie die folgenden Deklarationen (dies ist ein kleiner Hack):

    #sizeTest { font-size: 10px; } @media (min-width: 30em) { #sizeTest { font-size: 30px; } }

    APP.getState prüft die Schriftgröße dieses Elements, um eine Zeichenfolge zurückzugeben (die Sie definieren können): entweder klein oder groß . Wir haben andere Ansätze ausprobiert, aber dies bietet die beste browser- / geräteübergreifende Unterstützung. Dies kann dann verwendet werden, um den Logikfluss unseres JavaScript zu steuern. NAV.toggleSubNav wird:

    toggleSubNav: function(e) { e.preventDefault(); if ( APP.getState() === 'small' ) { $(this).siblings('ul').stop().slideToggle('fast'); } }

    Jetzt erfolgt das Umschalten von JavaScript nur noch bei kleinen Größen.

    Fazit

    Zu diesem Zeitpunkt sollten Sie eine ziemlich solide Navigation haben, die fast überall funktioniert. Wenn Sie weiter vertiefen möchten, würde ich empfehlen, zu folgen Scott Jehl , Brad Frost und Sparkbox : Wir haben nur die Oberfläche unserer Möglichkeiten zur Verbesserung unserer reaktionsschnellen Websites mithilfe von JavaScript zerkratzt.

    Wörter: Rob Tarr

    Dieser Artikel von Rob Tarr ursprünglich erschien in Netzmagazin Ausgabe 245.