În tutorialul din ziua de azi, vom folosi un pic de CSS și JavaScript pentru a crea un efect de hover al fanilor. Nu este un rezultat final complicat, dar construirea acestuia va fi o mare oportunitate de a ne practica abilitățile de capăt.
Fără altă intro, hai să vedem ce vom construi:
Începem cu un marcaj de bază; A nav
element care conține meniul și un spațiu gol deschidere
element:
Cu pregătirea marcajului, vom specifica câteva stiluri de bază pentru elementele legate:
.mynav ul afișare: flex; justify-content: centru; flex-wrap: folie; listă-tip: none; umplutura: 0; .mynav li: nu (: ultimul-copil) margin-right: 20px; .mynav a display: bloc; font-size: 20px; culoarea neagra; text-decoration: nici unul; padding: 7px 15px; .target poziție: absolută; margine de fund: 4px solid transparent; indicele z: -1; transformă: translateX (-60px); .mynav a, .target tranziție: toate .35s ușurință în afară;
Observați că deschidere
element (.ţintă
) Este absolut poziționată. După cum vom vedea într-un moment, vom folosi JavaScript pentru a determina poziția exactă. În plus, ar trebui să apară in spate link-urile de meniu, deci îi dăm un negativ z-index
.
În acest moment, hai să ne concentrăm atenția asupra JavaScript-ului necesar. În primul rând, direcționăm elementele dorite. De asemenea, definim o serie de culori pe care le vom folosi ulterior.
const țintă = document.querySelector (". target"); const link = document.querySelectorAll (".minav a"); const culori = ["deepskyblue", "portocaliu", "firebrick", "aur", "magenta", "negru", "închis");
Apoi ascultăm pentru clic
și mouseenter
evenimentele din legăturile de meniu.
Cand clic
evenimentul se întâmplă, împiedicăm reîncărcarea paginii. Desigur, acest lucru funcționează în cazul nostru, deoarece toate legăturile au un gol href
atribut. Într-un proiect real, însă, fiecare dintre legăturile de meniu ar deschide probabil o pagină diferită.
Cel mai important, de îndată ce mouseenter
incendii eveniment, mouseenterFunc
funcția de apel invers este executată:
pentru (let i = 0; i < links.length; i++) links[i].addEventListener("click", (e) => e.preventDefault ()); linkuri [i] .addEventListener ("mouseenter", mouseenterFunc);
Corpul mouseenterFunc
funcționează astfel:
funcția mousecenterFunc () pentru (let 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";
În cadrul acestei funcții, facem următoarele:
activ
clasa părintelui imediat (Li
) a legăturii țintă.opacitate
din toate link-urile de meniu, în afară de cea "activă".getBoundingClientRect
pentru a recupera mărimea legăturii asociate și poziția acesteia față de portul de vizualizare. border-color
proprietate a deschidere
element. Rețineți că valoarea inițială a proprietății este setată la transparent
.getBoundingClientRect
metodă pentru proprietățile corespunzătoare ale deschidere
element. Cu alte cuvinte, deschidere
eticheta moștenește mărimea și poziția legăturii care este plină.deschidere
element. Acest comportament este important doar pentru prima dată când plasăm cursorul peste o legătură. În acest caz, transformarea elementului trece de la transformare: translateX (-60px)
la transforma: nici unul
. Asta ne dă un efect frumos de alunecare.Este important să rețineți că codul de mai sus este executat de fiecare dată când plasăm cursorul peste un link. Prin urmare, rulează atunci când vom trece peste un link "activ", de asemenea. Pentru a preveni acest comportament, înfășurăm codul de mai sus într-un dacă
afirmație:
funcția mousecenterFunc () if (! this.parentNode.classList.contains ("active")) // cod aici
Până acum, demo-ul nostru arată după cum urmează:
Deci, totul pare să funcționeze așa cum era de așteptat, nu? Ei bine, nu este adevărat, pentru că dacă parcurgem pagina sau redimensionăm fereastra de vizualizare și apoi încercăm să selectăm o legătură, lucrurile se încurcă. În mod specific, poziția deschidere
elementul devine incorect.
Redați-vă cu demonstrația completă a paginii (asigurați-vă că ați adăugat conținut suficient de inactiv) pentru a vedea ce vreau să spun.
Pentru ao rezolva, trebuie să calculați cât de departe am derulat din partea superioară a ferestrei și adăugați această valoare la curent top
valoarea elementului țintă. În același mod, ar trebui să calculați cât de departe documentul a fost derulat orizontal (doar în caz). Valoarea rezultată este adăugată curentului stânga
valoarea elementului țintă.
Iată cele două linii de cod pe care le actualizăm:
const stânga = this.getBoundingClientRect () left + window.pageXOffset; const top = this.getBoundingClientRect () top + fereastră.pageYOffset;
Rețineți că tot codul de mai sus este executat imediat ce browserul procesează DOM și găsește scriptul relevant. Din nou, pentru propriile implementări și desene sau modele ar putea să doriți să executați acest cod atunci când pagina se încarcă sau ceva de genul ăsta. Într-un astfel de scenariu, va trebui să îl încorporați într-un handler de evenimente (de ex. sarcină
organizatorul evenimentului).
Ultimul lucru pe care trebuie să-l facem este să ne asigurăm că efectul va continua să funcționeze pe măsură ce redimensionăm fereastra browserului. Pentru a realiza acest lucru, ascultăm pentru redimensiona
eveniment și înregistrarea resizeFunc
organizatorul evenimentului.
window.addEventListener ("redimensionare", resizeFunc);
Iată corpul acestui manipulator:
funcția resizeFunc () const activ = document.querySelector (".mynav li.active"); dacă (activ) const stânga = activ.getBoundingClientRect () left + window.pageXOffset; const top = activ.getBoundingClientRect () top + fereastră.pageYOffset; target.style.left = '$ left px'; target.style.top = '$ top px';
În interiorul funcției de mai sus, facem următoarele:
activ
. În cazul în care există este un astfel de element, care afirmă că am mai trecut pe o legătură.stânga
și top
proprietățile elementului "activ", împreună cu proprietățile ferestrei asociate și le atribuie acestora deschidere
element. Rețineți că vom prelua valorile numai pentru proprietățile care se modifică în timpul redimensiona
eveniment. Aceasta înseamnă că nu este nevoie să recalculați lățimea și înălțimea legăturilor de meniu.Demo-ul funcționează bine în toate browserele recente. Dacă totuși întâmpinați probleme, anunțați-ne în comentariile de mai jos. De asemenea, după cum ați observat, folosim Babel pentru a ne compila codul ES6 până la ES5.
În acest tutorial am trecut prin procesul de creare a unui efect simplu, dar interesant, de hovering în meniu.
Sper că v-ați bucurat de ceea ce am construit aici și am inspirat dezvoltarea unor efecte de meniu chiar mai puternice, cum ar fi cea care apare (în momentul redactării) în site-ul Stripe.
Ai creat vreodată ceva similar? Dacă da, asigurați-vă că ați împărtășit cu noi provocările cu care v-ați confruntat.