Dans le tutoriel d'aujourd'hui, nous allons utiliser un peu de CSS et de JavaScript pour créer un effet de survol de menu sophistiqué. Le résultat final n’est pas compliqué, mais le construire sera une excellente occasion de mettre en pratique nos compétences initiales..
Sans plus d'introduction, voyons ce que nous allons construire:
Nous commençons avec des balises très basiques; une nav
élément qui contient le menu et un vide envergure
élément:
Avec le balisage prêt, nous spécifions ensuite quelques styles de base pour les éléments associés:
.mynav ul display: flex; justifier-contenu: centre; enveloppe souple: enveloppe; type de style de liste: aucun; rembourrage: 0; .mynav li: not (: last-child) margin-right: 20px; .mynav a display: block; taille de police: 20px; la couleur noire; texte-décoration: aucun; rembourrage: 7px 15px; .target position: absolute; bord inférieur: transparent 4px; z-index: -1; transformer: translateX (-60px); .mynav a, .target transition: tous les fichiers .35s à l’aise;
Notez que le envergure
élément (.cible
) Est absolument positionné. Comme nous le verrons dans un instant, nous utiliserons JavaScript pour déterminer sa position exacte. En outre, il devrait apparaître derrière les liens de menu, donc nous lui donnons un négatif z-index
.
À ce stade, concentrons notre attention sur le code JavaScript requis. Pour commencer, nous ciblons les éléments souhaités. Nous définissons également un tableau de couleurs que nous utiliserons plus tard.
const target = document.querySelector (". target"); const links = document.querySelectorAll (". mynav a"); const colors = ["deepskyblue", "orange", "brique réfractaire", "or", "magenta", "noir", "bleu foncé"];
Ensuite, nous écoutons pour le Cliquez sur
et mouseenter
événements des liens de menu.
Quand le Cliquez sur
événement se produit, nous empêchons la page de recharger. Bien sûr, cela fonctionne dans notre cas car tous les liens ont un vide href
attribut. Cependant, dans un projet réel, chacun des liens de menu ouvrirait probablement une page différente..
Plus important encore, dès que le mouseenter
les événements, les mouseenterFunc
La fonction de rappel est exécutée:
pour (soit i = 0; i < links.length; i++) links[i].addEventListener("click", (e) => e.preventDefault ()); links [i] .addEventListener ("mouseenter", mouseenterFunc);
Le corps du mouseenterFunc
la fonction ressemble à ceci:
function mouseenterFunc () for (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";
Dans cette fonction, nous effectuons les tâches suivantes:
actif
classe au parent immédiat (li
) du lien cible.opacité
à partir de tous les liens de menu, à l'exception du lien «actif».getBoundingClientRect
méthode pour récupérer la taille du lien associé et sa position par rapport à la fenêtre d'affichage. couleur de la bordure
propriété du envergure
élément. N'oubliez pas que sa valeur de propriété initiale est définie sur transparent
.getBoundingClientRect
méthode aux propriétés correspondantes du envergure
élément. En d'autres termes, le envergure
balise hérite de la taille et de la position du lien survolé.envergure
élément. Ce comportement n’est important que la première fois que nous survolons un lien. Dans ce cas, la transformation de l'élément passe de transformer: translateX (-60px)
à transformer: aucun
. Cela nous donne un bel effet de diapositive.Il est important de noter que le code ci-dessus est exécuté chaque fois que nous survolons un lien. Il fonctionne donc lorsque nous survolons également un lien «actif». Pour éviter ce problème, nous encapsulons le code ci-dessus dans un si
déclaration:
function mouseenterFunc () if (! this.parentNode.classList.contains ("active")) // code ici
Jusqu'ici, notre démo ressemble à ceci:
Donc, tout semble fonctionner comme prévu, non? Eh bien, ce n'est pas vrai, car si nous faisons défiler la page, ou redimensionnons la fenêtre d'affichage, puis que nous essayons de sélectionner un lien, les choses se compliquent. Plus précisément, la position du envergure
l'élément devient incorrect.
Jouez avec la démo de la page complète (assurez-vous d'avoir ajouté suffisamment de contenu factice) pour voir ce que je veux dire.
Pour le résoudre, nous devons calculer la distance parcourue depuis le haut de la fenêtre et ajouter cette valeur à la valeur actuelle. Haut
valeur de l'élément cible. De la même manière, nous devrions calculer dans quelle mesure le document a été défilé horizontalement (juste au cas où). La valeur résultante est ajoutée à la valeur actuelle la gauche
valeur de l'élément cible.
Voici les deux lignes de code que nous mettons à jour:
const left = this.getBoundingClientRect (). left + window.pageXOffset; const top = this.getBoundingClientRect (). top + window.pageYOffset;
Gardez à l'esprit que tout le code ci-dessus est exécuté dès que le navigateur traite le DOM et trouve le script approprié. Encore une fois, pour vos propres implémentations et conceptions, vous souhaiterez peut-être exécuter ce code lors du chargement de la page, ou quelque chose du genre. Dans un tel scénario, vous devrez l’intégrer dans un gestionnaire d’événements (par exemple,. charge
gestionnaire d'événements).
La dernière chose à faire est de s’assurer que l’effet fonctionnera toujours lors du redimensionnement de la fenêtre du navigateur. Pour ce faire, nous écoutons le redimensionner
événement et enregistrer le resizeFunc
gestionnaire d'événements.
window.addEventListener ("resize", resizeFunc);
Voici le corps de ce gestionnaire:
fonction resizeFunc () const active = document.querySelector (".mynav li.active"); if (actif) const left = active.getBoundingClientRect (). left + window.pageXOffset; const top = active.getBoundingClientRect (). top + window.pageYOffset; target.style.left = '$ left px'; target.style.top = '$ top px';
Dans la fonction ci-dessus, nous procédons comme suit:
actif
. S'il y a est un tel élément, qui indique que nous avons déjà survolé un lien.la gauche
et Haut
propriétés de l’élément «actif» ainsi que les propriétés de la fenêtre associées et les affecter à la envergure
élément. Notez que nous récupérons les valeurs uniquement pour les propriétés qui changent au cours de la redimensionner
un événement. Cela signifie qu'il n'est pas nécessaire de recalculer la largeur et la hauteur des liens de menu..La démo fonctionne bien dans tous les navigateurs récents. Si toutefois vous rencontrez des problèmes, faites-le moi savoir dans les commentaires ci-dessous. En outre, comme vous l'avez peut-être remarqué, nous utilisons Babel pour compiler notre code ES6 jusqu'à ES5..
Dans ce tutoriel, nous avons décrit le processus de création d’un effet de survol de menu simple mais intéressant..
J'espère que vous avez apprécié ce que nous avons construit ici et que vous avez trouvé l'inspiration pour développer des effets de menu encore plus puissants, comme celui qui apparaît (au moment de l'écriture) sur le site Stripe..
Avez-vous déjà créé quelque chose de similaire? Si oui, assurez-vous de partager avec nous les défis que vous avez rencontrés.