J'ai un événement mouseenter sur deux éléments. Le mouseenter montre un div avec le contenu; Et dans chaque div se trouve un bouton dans lequel je voudrais attacher un événement pour écouter un clic ou tap qui permettrait de se retirer c'est-à-dire le div.
Voici le script de jQuery:
$(document).ready(function() {
var $subnav = $('.subnav');
$(".close").on('click tap', function(e) {
if (!$subnav) {
$subnav.show();
}
$subnav.hide();
});
$('.discover:hover, .watch:hover').on({
mouseenter: function() {
if (!$subnav) {
$subnav.show();
}
$subnav.hide();
},
mouseleave: function() {
if ($subnav) {
$subnav.hide();
}
$subnav.show();
}
}
<nav>
<ul class="nav-categories discover-active">
<li class="nav-category-and-subnav discover">
<div id="discover" class="nav-category">
<span class="nav-category-padding">Discover</span>
<i class="fa fa-angle-down" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" width="1792" height="1792" viewBox="0 0 1792 1792">
<path d="M1395 736q0 13-10 23l-466 466q-10 10-23 10t-23-10L407 759q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23z"></path>
</svg>
</i>
<div class="subnav">
<a href="https://jump.refinery29.com/join/24/signup-ca-refresh"><img src="images/thisweek.jpg"></a>
<p class="close">X</p>
</div>
</div>
</li>
<li class="nav-category-and-subnav watch">
<div id="watch" class="nav-category">
<span class="nav-category-padding">Watch</span>
<i class="fa fa-angle-down" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" width="1792" height="1792" viewBox="0 0 1792 1792">
<path d="M1395 736q0 13-10 23l-466 466q-10 10-23 10t-23-10L407 759q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23z"></path>
</svg>
</i>
<div class="subnav">
<div class="column">
Original Series
</div>
<div class="column">
Trending Videos
</div>
<p class="close">X</p>
</div>
</div>
</li>
</ul>
</nav>
header nav ul:not(:hover).discover-active .discover .nav-category {
color: #ef4b4b;
}
nav ul li .nav-category {
padding: 0 15px 0 30px;
height: 58px;
position: relative;
}
nav ul:not(:hover).discover-active .discover .nav-category:before {
background-color: #ef4b4b;
content: "";
position: absolute;
left: 0;
height: 4px;
width: 100%;
}
header nav .nav-categories .nav-category-and-subnav.discover:hover .nav-category:before {
background-color: #ef4b4b;
content: "";
position: absolute;
left: 0;
height: 4px;
width: 100%;
}
header nav .nav-categories .nav-category-and-subnav.watch:hover .nav-category:before {
background-color: #e5059a;
content: "";
position: absolute;
left: 0;
height: 4px;
width: 100%;
}
.discover .subnav,
.watch .subnav,
.global-site-switch .subnav {
display: none;
}
.discover .subnav img {
width: 100%;
}
header nav .nav-categories .nav-category-and-subnav.discover:hover .subnav {
background-color: #000;
position: fixed;
display: block;
left: 0;
right: 0;
margin: 0 auto;
top: 59px;
height: 530px;
width: 635px;
}
header nav .nav-categories .nav-category-and-subnav.watch:hover .subnav {
background-color: #000;
position: fixed;
display: block;
left: 0;
right: 0;
margin: 0 auto;
top: 59px;
height: 530px;
width: 635px;
}
$(function() {
var $subnav = $('.subnav');
$("#discover #watch").on({
mouseenter: function(e) {
$subnav.show();
$(".close").on('click tap', function(e) {
if ($subnav) $subnav.hide();
else $subnav.show();
});
},
mouseleave: function() {
$subnav.hide();
}
});
});
Qu'est-ce que je fais de mal?
MISE À JOUR
Apparemment, j'ai dû mettre à jour le script parce que je ne savais pas que c'était Code CSS qui était en conflit avec le JS. Pour contourner le problème, je dois utiliser les sélecteurs jQuery pour sélectionner les états : hover . Ce script ne fonctionne qu'une seule fois.
$(function() {
var $subnav = $('.subnav');
$("#discover #watch").on({
mouseenter: function(e) {
$subnav.show();
$(".close").on('click tap', function(e) {
if ($subnav) $subnav.hide();
else $subnav.show();
});
},
mouseleave: function() {
$subnav.hide();
}
});
4 Réponses :
Vous devez trouver le bouton dans le contexte de l'élément cliqué:
$(e.target).find(".close").on ....
Retirez l'écouteur d'événement de clic .close de l'écouteur mouseenter existant et ciblez l'élément parent.
$(".close").on('click tap', function(e) {
$(this).parent().hide();
});
SOLUTION MISE À JOUR
J'ai également supprimé l'instruction conditionnelle, comme si l'élément .close ne pouvait être cliqué que si le parent est visible, il n'est donc pas nécessaire de regarder pour un "parent caché"
Veuillez ajouter une virgule entre les deux sélecteurs d'id => #discover, #watch. Enveloppez le code dans le document prêt à être sûr et placez le gestionnaire d'événements close en dehors de l'entrée / sortie de la souris pour qu'il ne l'applique qu'une seule fois. Voir le code ci-dessous:
$(document).ready(function () {
var $subnav = $('.subnav');
$(".close").on('click tap', function (e) {
if ($subnav) $subnav.hide();
else $subnav.show();
});
$("#discover, #watch").on({
mouseenter: function (e) {
$subnav.show();
},
mouseleave: function () {
$subnav.hide();
}
});
});
Si vous souhaitez utiliser du JavaScript pur, vous devez:
Assurez-vous que vos deux divs subnav sont masqués par défaut en ajoutant une propriété display: none; css à vos divs subnav .
Vous pouvez ensuite utiliser getComputedStyle () pour récupérer cette valeur de propriété display et en fonction de cette valeur récupérée, vous pouvez continuer et basculer la propriété d'affichage subnav chaque fois qu'un mouseenter ou l'événement mouseleave est déclenché.
Enfin, vous pouvez utiliser parentElement () pour fermer le div subnav parent chaque fois que l'utilisateur clique sur l'élément X enfant.
Vous pouvez consulter un exemple pratique de ce que j'ai décrit ci-dessus dans ce jsFiddle ou dans l ' extrait de code ci-dessous:
<nav>
<ul>
<li>
<div id="discover" class="nav-category">
<span>Discover</span>
<p>
SVG here
</p>
<div class="subnav">
<p>
IMG here
</p>
<p class="close">X</p>
</div>
</div>
</li>
<hr>
<li>
<div id="watch" class="nav-category">
<span>Watch</span>
<p>
SVG here
</p>
<div class="subnav">
<div class="column">
Original Series
</div>
<div class="column">
Trending Videos
</div>
<p class="close">X</p>
</div>
</div>
</li>
</ul>
</nav>
.subnav { background: green;display: none;}
var discover = document.getElementById("discover");
var watch = document.getElementById("watch");
var close = document.querySelectorAll(".close");
function openSub(e) {
var subNav = e.target.childNodes[5];
var x = window.getComputedStyle(subNav);
if (x.display == "none") {
subNav.style.display = "block";
} else {
subNav.style.display = "none";
}
}
function closeSub(e) {
var subNav = e.target.childNodes[5];
subNav.style.display = "none";
}
discover.addEventListener("mouseenter", openSub);
watch.addEventListener("mouseenter", openSub);
discover.addEventListener("mouseleave", closeSub);
watch.addEventListener("mouseleave", closeSub);
function btnSub(e) {
e.target.parentElement.style.display = "none";
}
close.forEach(btn => {
btn.addEventListener("click", btnSub);
});
Êtes-vous ouvert à une approche JavaScript pure ou souhaitez-vous uniquement une solution utilisant jQuery?
Évitez de créer des écouteurs d'événements dans d'autres écouteurs d'événements. Il s'agit d'un moyen rapide de dupliquer la liaison et de créer des problèmes de logique et de performances.
De plus, étant donné que la répétition des identifiants est un non-non majeur,
$ ("# discover #watch")devrait simplement être$ ("# watch")comme il ne devrait y en avoir que être un par page.@AndrewL Pure JS serait FAB!