1
votes

Le menu déroulant disparaît lorsque vous essayez de survoler les éléments du menu

J'ai créé un menu de base avec une seule liste déroulante. Lorsque je survole l'élément du menu principal, le menu déroulant apparaît. Lorsque j'essaie de sélectionner un élément de menu dans la liste déroulante, il disparaît. J'ai placé la liste déroulante en dehors de l'élément ul li car j'ai besoin qu'elle soit pleine largeur et le placer à l'intérieur du li ne le permettrait pas.

HTML

 $('.dd-link').on({
    mouseenter: function() {
        $('.dd-menu').stop(true, true).fadeIn(fadeSpeed);
    },
    mouseleave: function() {
        $('.dd-menu').stop(true, true).fadeOut(fadeSpeed);
    }
});  

CSS

ul {
    list-style: none;
}

 ul li {
    display: inline-block;
}

 ul li ul li {
    display: inline-block;
}

.dd-menu {
    position:absolute;
    top: 24px;
    left: 0;
    width: 100%;
    display: none;
    background-color: #def;
}

JS

<header>
    <div class="container">
        <div class="row">
            <div class="col-3">
                <a href="">Logo</a>
            </div>

            <div class="col-9">
                         <ul>
                             <li><a href="">Link 1</a></li>
                             <li class="dd-link"><a href="">Link 2</a></li>
                         </ul>
            </div>
        </div>


    <div class="dd-menu">
        <a href="">DD Menu 1</a>
        <a href="">DD Menu 2</a>
    </div>
</header>


7 commentaires

Avez-vous également du CSS?


Le problème, c'est que la souris quitte le menu .dd lorsque vous survolez les liens ... vous devez les envelopper dans l'autre.


Donc, vous dites que je dois placer .dd-menu dans le li ?


Oui, j'ai publié une réponse démontrant une solution.


Et il n'y a vraiment pas besoin de JavaScript. Le CSS pur peut le faire.


Alyus - La réponse d'Epascarello est excellente. Vous pouvez simplement ajouter à gauche: 0; à droite: 0; au style nav li> ul pour obtenir des sous-menus pleine largeur.


Même le menu principal et la liste déroulante sont-ils dans une grille?


3 Réponses :


2
votes

Lorsque vous déplacez votre souris du .dd-link vers le nouveau .dd-menu , vous déclenchez en fait l'événement mouseleave et cachez-les. Si le menu se trouve dans la classe d'élément qui le déclenche (comme ci-dessous), tout va bien car vous ne quittez jamais l'élément parent.

Vous pouvez également le faire avec du CSS pur, ce qui est plus conseillé. Il y a une deuxième démo ci-dessous la démonstration de jquery.


Démo de Jquery

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>

  <div class="navbar">

    <ul class="navmenu">
      <li><a href="">Link 1</a></li>
      <li class="dd-link"><a href="">Link 2
        </a>
        <div class="dd-menu">
          <a href="">DD Menu 1</a>
          <a href="">DD Menu 2</a>
        </div>
      </li>
    </ul>

  </div>
</header>
.navbar {
  height: 24px;
  position: absolute;
  left: 0;
  right: 0;
  background: black;
}

ul.navmenu {
  list-style: none;
  margin: 0px;
  padding: 0px;
}

ul.navmenu a {
  color: white;
  line-height: 24px;
  text-decoration: none;
}

ul.navmenu li {
  display: inline-block;
  margin-left: 10px;
}

.dd-menu {
  position: absolute;
  top: 24px;
  left: 0;
  right: 0;
  opacity: 0;
  background-color: #def;
}

.dd-link:hover .dd-menu {
  opacity: 1;
  transition: .3s;
}

ul.navmenu .dd-menu a {
  color: black;
}
fadeSpeed = 300;
$('.dd-link').on({
  mouseenter: function() {
    $('.dd-menu').stop(true, true).fadeIn(fadeSpeed);
  },
  mouseleave: function() {
    $('.dd-menu').stop(true, true).fadeOut(fadeSpeed);
  }
});

Démo CSS

<ul  class="menu">
      
      <li><a href="">Link 1</a></li>
        
        <li class="dd-link">
        
        <a href="">Link 2</a>
        
          <div class="dd-menu">
            <a href="">DD Menu 1</a><br>
            <a href="">DD Menu 2</a>
          </div>
        
        </li>
      
      </ul>
.menu li{
  list-style-type: none;
}

.dd-menu {
  opacity: 0;
}

.dd-link:hover .dd-menu {
  opacity: 1;
  transition: .3s;
}

Démo pour votre exemple spécifique

J'ai ajouté quelques classes et un style supplémentaire pour créer un menu de navigation typique avec votre structure. J'espère que cela aidera.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
  <ul>
  
  <li><a href="">Link 1</a></li>
    
    <li class="dd-link">
    
    <a href="">Link 2</a>
    
      <div class="dd-menu">
        <a href="">DD Menu 1</a>
        <a href="">DD Menu 2</a>
      </div>
    
    </li>
  
  </ul>


</header>
.dd-menu {
  display: none;
}
fadeSpeed = 300;
$('.dd-link').on({
  mouseenter: function() {
    $('.dd-menu').stop(true, true).fadeIn(fadeSpeed);
  },
  mouseleave: function() {
    $('.dd-menu').stop(true, true).fadeOut(fadeSpeed);
  }
});


3 commentaires

J'ai appliqué votre suggestion de placer le menu déroulant à l'intérieur du li , cependant, le menu déroulant ne couvre pas toute la largeur de la page, c'est pourquoi je pense avoir placé le menu déroulant en dehors du < élément code> ul .


Mis à jour pour inclure un exemple pour votre situation, mais vous devriez consulter la réponse d'epascerello


Merci pour l'exemple, cependant, j'ai également commis une erreur dans mon code initial. J'ai mis à jour mon code.



1
votes

Il se cache parce que la souris se déplace à l'extérieur du li. Donc, pour que votre code fonctionne, le code doit être dans le li ou vous devez ajouter une logique compliquée pour voir si l'élément sur lequel vous vous êtes concentré est le sous-menu.

La chose la plus simple est que le CSS simple peut faire apparaître des menus en survol, pas besoin de JavaScript. Placez le sous-navigateur dans le li et appliquez le survol à votre li.

<nav>
  <ul>
    <li>
      <a href="#">Text 1</a>
      <ul>
        <li><a href="#">Text 1 - 1</a></li>
        <li><a href="#">Text 1 - 2</a></li>
        <li><a href="#">Text 1 - 3</a></li>
      </ul>
    </li>
    <li>
      <a href="#">Text 2</a>
      <ul>
        <li><a href="#">Text 2 - 1 with longer text than whatever</a></li>
        <li><a href="#">Text 2 - 2</a></li>
        <li><a href="#">Text 2 - 3</a></li>
        <li><a href="#">Text 2 - 4</a></li>
      </ul>
    </li>
  </ul>
</nav>
nav ul {
  padding: 0;
  margin: 0;
}

nav li {
  list-style-type: none;
  padding: .5em;
  margin: 0;
}

nav > ul > li {
  display: inline-block;
}

nav li > ul {
  position: absolute;
  background-color: #CCC;
  max-height: 0;
  opacity:0;
  transition: max-height 0.25s ease-out, opacity 0.25s ease-out;
  overflow: hidden;
}


nav li:hover > ul,
nav li:focus-within ul {
  max-height: 500px;
  opacity: 1;
  transition: max-height 0.75s ease-out, opacity 0.75s ease-out;
}


1 commentaires

Merci pour l'exemple, cependant, mon code précédent manquait quelques éléments. La liste déroulante est placée dans une grille et doit également être pleine largeur lorsqu'elle est visible. L'une des raisons pour lesquelles j'ai placé la liste déroulante à l'extérieur du menu principal.



0
votes

Vous pouvez ajouter les mêmes événements à .dd-menu et ne pas définir jumpToEnd dans les méthodes .stop () sur true :

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
  <div class="container">
    <div class="row">
      <div class="col-3">
        <a href="">Logo</a>
      </div>
      <div class="col-9">
        <ul>
          <li><a href="">Link 1</a></li>
          <li class="dd-link"><a href="">Link 2</a></li>
        </ul>
      </div>
    </div>
  </div>
  <div class="dd-menu">
    <a href="">DD Menu 1</a>
    <a href="">DD Menu 2</a>
  </div>
</header>

Démo

ul {
  list-style: none;
}
ul li {
  display: inline-block;
}
ul li ul li {
  display: inline-block;
}
.dd-menu {
  position:absolute;
  top: 24px;
  left: 0;
  width: 100%;
  display: none;
  background-color: #def;
}
var fadeSpeed = 300;

$('.dd-link, .dd-menu').on({
  mouseenter: function() {
    $('.dd-menu').stop(true).fadeIn(fadeSpeed);
  },
  mouseleave: function() {
    $('.dd-menu').stop(true).fadeOut(fadeSpeed);
  }
});
$('.dd-link, .dd-menu').on({
  mouseenter: function() {
    $('.dd-menu').stop(true).fadeIn(fadeSpeed);
  },
  mouseleave: function() {
    $('.dd-menu').stop(true).fadeOut(fadeSpeed);
  }
});


0 commentaires