I dagens veiledning skal vi bruke en liten bit av CSS og JavaScript for å lage en fancy meny-hover-effekt. Det er ikke et komplisert sluttresultat, men å bygge det vil være en flott mulighet til å øve våre ferdigheter.
Uten ytterligere intro, la oss sjekke ut hva vi skal bygge:
Vi starter med noen veldig grunnleggende oppslag; en nav
element som inneholder menyen og en tom span
element:
Med markup klar, neste vi spesifiserer noen grunnleggende stiler for de relaterte elementene:
.mynav ul display: flex; begrunn-innhold: center; flex-wrap: wrap; liste-stil-type: none; polstring: 0; .mynav li: ikke (: siste barn) margin-right: 20px; .mynav a display: block; skriftstørrelse: 20px; farge svart; tekst-dekorasjon: ingen; polstring: 7px 15px; .target posisjon: absolutt; grensebunn: 4px solid gjennomsiktig; z-indeks: -1; transformere: translateX (-60px); .mynav a, .target overgang: alle .35s brukervennlighet;
Legg merke til at span
element (.mål
) Er helt posisjonert. Som vi ser om et øyeblikk, bruker vi JavaScript til å bestemme sin eksakte posisjon. I tillegg bør det vises bak menyen kobler, så vi gir det en negativ z-indeks
.
På dette punktet, la oss fokusere vår oppmerksomhet på det nødvendige JavaScript. Til å begynne med målretter vi mot de ønskede elementene. Vi definerer også en rekke farger som vi vil bruke senere.
const target = document.querySelector (". target"); const links = document.querySelectorAll (".mynav a"); const colors = ["deepskyblue", "orange", "firebrick", "gold", "magenta", "black", "darkblue");
Neste lytter vi etter klikk
og mouseenter
hendelser i menykoblingene.
Når klikk
Hendelsen skjer, vi forhindrer at siden lastes ned. Selvfølgelig virker dette i vårt tilfelle fordi alle koblinger har en tom href
Egenskap. I et ekte prosjekt vil imidlertid hver menykobling sannsynligvis åpne en annen side.
Viktigst, så snart som mouseenter
hendelsesbranner, mouseenterFunc
tilbakeringingsfunksjon utføres:
for (la jeg = 0; jeg < links.length; i++) links[i].addEventListener("click", (e) => e.preventDefault ()); lenker [i] .addEventListener ("mouseenter", mouseenterFunc);
Kroppen til mouseenterFunc
funksjonen ser slik ut:
funksjon mouseenterFunc () for (la i = 0; jeg < 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";
Inne i denne funksjonen gjør vi følgende:
aktiv
klasse til nærmeste forelder (li
) av mållinken.opasitet
fra alle menykoblinger, bortsett fra den "aktive" en.getBoundingClientRect
metode for å hente størrelsen på den tilknyttede lenken og dens posisjon i forhold til visningsporten. grensefarge
eiendom av span
element. Husk at den opprinnelige eiendomsverdien er satt til gjennomsiktig
.getBoundingClientRect
metode til de tilsvarende egenskapene til span
element. Med andre ord, span
tag arver størrelsen og posisjonen til lenken som hovered over.span
element. Denne oppførselen er bare viktig første gang vi svinger over en lenke. I dette tilfellet går transformasjonen av elementet fra transformere: translateX (-60px)
til transformere: ingen
. Det gir oss en fin lysbildeffekt.Det er viktig å merke seg at koden ovenfor blir utført hver gang vi svinger over en lenke. Det kjører derfor når vi svinger over en "aktiv" kobling også. For å forhindre denne oppførselen, pakker vi inn koden ovenfor inne i en hvis
uttalelse:
funksjon mouseenterFunc () hvis (! this.parentNode.classList.contains ("active")) // kode her
Så langt ser vår demo ut som følger:
Så, alt ser ut til å fungere som forventet, ikke sant? Vel, det er ikke sant fordi hvis vi rulle gjennom siden, eller endre størrelsen på visningsporten, og deretter prøve å velge en kobling, blir ting rotete. Spesielt posisjonen til span
elementet blir feil.
Spille rundt med demonstrasjonen på hele siden (sørg for at du har lagt til nok dummyinnhold) for å se hva jeg mener.
For å løse det må vi beregne hvor langt vi har rullet fra toppen av vinduet og legg til denne verdien til gjeldende topp
verdien av målelementet. På samme måte skal vi beregne hvor langt dokumentet er rullet horisontalt (bare i tilfelle). Den resulterende verdien legges til gjeldende venstre
verdien av målelementet.
Her er de to kodelinjene som vi oppdaterer:
const left = this.getBoundingClientRect (). left + window.pageXOffset; const top = this.getBoundingClientRect (). toppen + window.pageYOffset;
Husk at hele koden ovenfor blir utført så snart nettleseren behandler DOM og finner det aktuelle skriptet. Igjen, for dine egne implementeringer og design, vil du kanskje kjøre denne koden når siden lastes, eller noe sånt. I et slikt scenario må du legge det inn i en hendelseshandler (f.eks. laste
hendelsehandler).
Det siste vi må gjøre er å sikre at effekten fortsatt fungerer når vi endrer størrelsen på nettleservinduet. For å oppnå dette, lytter vi etter endre størrelse på
hendelse og registrer resizeFunc
hendelse handler.
window.addEventListener ("resize", resizeFunc);
Her er kroppen til denne handleren:
funksjon resizeFunc () const active = document.querySelector (".mynav li.active"); hvis (aktiv) const left = active.getBoundingClientRect (). left + window.pageXOffset; const top = active.getBoundingClientRect (). toppen + window.pageYOffset; target.style.left = '$ left px'; target.style.top = '$ top px';
Innenfor funksjonen ovenfor gjør vi følgende:
aktiv
. Hvis det er er Et slikt element, som sier at vi allerede har svevet over en lenke.venstre
og topp
egenskaper av det "aktive" elementet sammen med tilhørende vinduegenskaper og tilordne dem til span
element. Vær oppmerksom på at vi bare henter verdiene for egenskapene som endres under endre størrelse på
begivenhet. Det betyr at det ikke er nødvendig å beregne bredden og høyden på menykoblingene.Demoen fungerer bra i alle nyere nettlesere. Hvis du støter på noen problemer, vennligst gi meg beskjed i kommentarene nedenfor. Også, som du kanskje har lagt merke til, bruker vi Babel til å kompilere ES6-koden ned til ES5.
I denne opplæringen gikk vi gjennom prosessen med å skape en enkel, men likevel interessant meny-hover-effekt.
Jeg håper du likte det vi bygde her og tok inspirasjon for å utvikle enda kraftigere menyeffekter som den som vises (på skrivingstidspunktet) i Stripesiden.
Har du noen gang opprettet noe lignende? I så fall må du dele med oss de utfordringene du møtte.