Im heutigen Tutorial verwenden wir ein wenig CSS und JavaScript, um einen ausgefallenen Menü-Hover-Effekt zu erzeugen. Es ist kein kompliziertes Endergebnis, aber das Bauen ist eine großartige Gelegenheit, unsere Frontend-Fähigkeiten zu üben.
Lassen Sie uns ohne weitere Einführung prüfen, was wir bauen werden:
Wir beginnen mit einem sehr einfachen Markup. ein nav
Element, das das Menü und ein leeres enthält Spanne
Element:
Wenn das Markup fertig ist, geben wir als Nächstes einige grundlegende Stile für die zugehörigen Elemente an:
.mynav ul display: flex; Inhalt rechtfertigen: Mitte; Flex-Wrap: Wrap; Typ des Listentyps: keine; Polsterung: 0; .mynav li: nicht (: letztes Kind) margin-right: 20px; .mynav a display: block; Schriftgröße: 20px; Farbe schwarz; Textdekoration: keine; Polsterung: 7px 15px; .target position: absolut; Rand unten: 4px durchsichtig transparent; z-Index: -1; transform: translateX (-60px); .mynav a, .target Übergang: alle .35s-Inaktivität;
Beachten Sie, dass die Spanne
Element (.Ziel
) Ist absolut positioniert. Wie wir gleich sehen werden, verwenden wir JavaScript, um die genaue Position zu bestimmen. Außerdem sollte es erscheinen hinter Das Menü verlinkt, also geben wir es negativ z-index
.
An dieser Stelle konzentrieren wir uns auf das erforderliche JavaScript. Zunächst zielen wir auf die gewünschten Elemente. Wir definieren auch eine Reihe von Farben, die wir später verwenden werden.
const target = document.querySelector (". target"); const links = document.querySelectorAll (". mynav a"); const colors = ["deepskyblue", "orange", "firebrick", "gold", "magenta", "schwarz", "darkblue"];
Als nächstes hören wir auf die klicken
und Mouseenter
Ereignisse der Menülinks.
Wenn der klicken
Wenn ein Ereignis auftritt, wird verhindert, dass die Seite erneut geladen wird. Das funktioniert natürlich in unserem Fall, da alle Links leer sind href
Attribut. In einem realen Projekt würde jedoch wahrscheinlich jeder der Menü-Links eine andere Seite öffnen.
Am wichtigsten ist, sobald die Mouseenter
Ereignis brennt, die mouseenterFunc
Callback-Funktion wird ausgeführt:
für (sei i = 0; i < links.length; i++) links[i].addEventListener("click", (e) => e.preventDefault ()); links [i] .addEventListener ("mouseenter", mouseenterFunc);
Der Körper der mouseenterFunc
Funktion sieht so aus:
function mouseenterFunc () for (sei i = 0; i < links.length; i++) if (links[i].parentNode.classList.contains("active")) links[i].parentNode.classList.remove("active"); links[i].style.opacity = "0.25"; this.parentNode.classList.add("active"); this.style.opacity = "1"; const width = this.getBoundingClientRect().width; const height = this.getBoundingClientRect().height; const left = this.getBoundingClientRect().left; const top = this.getBoundingClientRect().top; const color = colors[Math.floor(Math.random() * colors.length)]; target.style.width = '$widthpx'; target.style.height = '$heightpx'; target.style.left = '$leftpx'; target.style.top = '$toppx'; target.style.borderColor = color; target.style.transform = "none";
Innerhalb dieser Funktion führen wir Folgendes aus:
aktiv
Klasse zum unmittelbaren Elternteil (li
) des Ziellinks.Opazität
von allen Menü-Links außer dem "aktiven".getBoundingClientRect
Methode, um die Größe des verknüpften Links und seine Position relativ zum Viewport abzurufen. Randfarbe
Eigentum der Spanne
Element. Denken Sie daran, dass der anfängliche Eigenschaftswert auf festgelegt ist transparent
.getBoundingClientRect
Methode auf die entsprechenden Eigenschaften des Spanne
Element. Mit anderen Worten, die Spanne
Das Tag erbt die Größe und die Position des Links, über den sich der Mauszeiger bewegt.Spanne
Element. Dieses Verhalten ist nur wichtig, wenn wir zum ersten Mal über einen Link fahren. In diesem Fall geht die Transformation des Elements von aus transform: translateX (-60px)
zu verwandeln: keine
. Das gibt uns einen schönen Slide-In-Effekt.Es ist wichtig zu wissen, dass der obige Code jedes Mal ausgeführt wird, wenn wir über einen Link fahren. Es läuft also, wenn wir auch über eine "aktive" Verbindung fahren. Um dieses Verhalten zu verhindern, wickeln wir den obigen Code in ein ob
Aussage:
function mouseenterFunc () if (! this.parentNode.classList.contains ("active")) // Code hier
Bisher sieht unsere Demo folgendermaßen aus:
Also scheint alles wie erwartet zu funktionieren, richtig? Nun, das stimmt nicht, denn wenn wir durch die Seite blättern oder die Größe des Ansichtsfensters ändern und dann versuchen, einen Link auszuwählen, werden die Dinge unordentlich. Insbesondere die Position der Spanne
Element wird falsch.
Spielen Sie mit der ganzseitigen Demo (stellen Sie sicher, dass Sie genügend Dummy-Inhalte hinzugefügt haben), um zu sehen, was ich meine.
Um das Problem zu lösen, müssen wir berechnen, wie weit wir vom oberen Rand des Fensters gescrollt wurden, und diesen Wert zum aktuellen Wert hinzufügen oben
Wert des Zielelements. Auf dieselbe Weise sollten wir berechnen, wie weit das Dokument horizontal verschoben wurde (nur für den Fall). Der resultierende Wert wird zum Strom addiert links
Wert des Zielelements.
Hier sind die zwei Codezeilen, die wir aktualisieren:
const left = this.getBoundingClientRect (). left + window.pageXOffset; const top = this.getBoundingClientRect (). top + window.pageYOffset;
Beachten Sie, dass der gesamte Code ausgeführt wird, sobald der Browser das DOM verarbeitet und das entsprechende Skript findet. Für Ihre eigenen Implementierungen und Designs möchten Sie möglicherweise diesen Code ausführen, wenn die Seite geladen wird, oder ähnliches. In einem solchen Szenario müssen Sie es in einen Event-Handler einbetten (z. Belastung
Eventhandler).
Das letzte, was wir tun müssen, ist sicherzustellen, dass der Effekt immer noch funktioniert, wenn wir die Größe des Browser-Fensters ändern. Um dies zu erreichen, hören wir auf die Größe ändern
Veranstaltung und Registrierung der resizeFunc
Eventhandler.
window.addEventListener ("resize", resizeFunc);
Hier ist der Körper dieses Handlers:
function resizeFunc () const active = document.querySelector (". mynav li.active"); if (aktiv) const left = active.getBoundingClientRect (). left + window.pageXOffset; const top = active.getBoundingClientRect (). top + window.pageYOffset; target.style.left = '$ left px'; target.style.top = '$ top px';
In der obigen Funktion führen wir Folgendes aus:
aktiv
. Wenn dort ist ein solches Element, das besagt, dass wir bereits über einen Link schwebten.links
und oben
Eigenschaften des „aktiven“ Elements zusammen mit den zugehörigen Fenstereigenschaften und weisen Sie diese dem zu Spanne
Element. Beachten Sie, dass wir die Werte nur für die Eigenschaften abrufen, die sich während der Änderung ändern Größe ändern
Veranstaltung. Das bedeutet, dass Sie die Breite und Höhe der Menü-Links nicht neu berechnen müssen.Die Demo funktioniert gut in allen aktuellen Browsern. Wenn Sie jedoch auf Probleme stoßen, teilen Sie mir dies in den Kommentaren mit. Wie Sie möglicherweise bereits bemerkt haben, verwenden wir Babel, um unseren ES6-Code auf ES5 herunterzukompilieren.
In diesem Tutorial haben wir einen einfachen, aber interessanten Menü-Hover-Effekt erstellt.
Ich hoffe, Ihnen hat das, was wir hier gebaut haben, Spaß gemacht, und Sie haben sich inspirieren lassen, noch leistungsfähigere Menüeffekte zu entwickeln, wie die, die (zum Zeitpunkt des Schreibens) auf der Stripe-Site erscheint.
Hast du schon einmal etwas Ähnliches geschaffen? Wenn ja, teilen Sie uns mit, welche Herausforderungen Sie hatten.