jQuery, Exit an item that I have not entered

2

Make a navigation bar with a drop-down menu that will be automatically displayed when you hover over an element of that bar and that when leaving the element is automatically hidden.

I have managed to do almost everything, but when I want the drop-down menu to disappear without having entered it, it does not work for me. Neither my teacher nor I have managed to find the answer and I am agreed that it is something super easy that escapes me.

Then I leave the whole code.

$(document).ready(function (){

	$(".dropdown-toggle").on("mouseover", function () {
		$(".dropdown-menu").show("slow");
	});	

	$(".dropdown-menu").on("mouseleave", function () {
		$(".dropdown-menu").hide("slow");
	});	
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navbar navbar-inverse" role="navigation">
       <div class="navbar-header"> 
            <a href="#" class="dropdown-toggle navbar-brand" data-toggle="dropdown">Menu 1 </a>
                        <ul class="dropdown-menu">
                            <li><a href="#">Action</a></li>
                            <li><a href="#">Another action</a></li>
                            <li><a href="#">Something else here</a></li>
                            <li><a href="#">Separated link</a></li>
                        </ul>
            <a href="#" class="navbar-brand"> Menu 2</a>
            <a href="#" class="navbar-brand"> Menu 3</a>
            <a href="#" class="navbar-brand"> Menu 4</a>
       </div> 
</nav>
    
asked by Alvaro Molina 12.07.2016 в 21:20
source

2 answers

1

Here is an alternative that requires changing the code a bit:

  • Move the menu items to a list
  • Make the drop-down menu a sublist
  • Passes the class dropdown-toggle to the first item in the list (the one containing the submenu / sublist)
  • Change the events so that both apply to dropdown-toggle
  • Convert event onmouseover in onmouseenter
  • Make the menu items occupy the entire height of it

When moving the sub-menu within a sublist and the onmouseenter event to the first menu item (containing the sublist), then the menu will be displayed whenever the mouse is hovered over that element and sub-list ( included).

Applying those changes, the code would look like this:

$(document).ready(function (){

	$(".dropdown-toggle").on("mouseenter", function () {
		$(".dropdown-menu").stop().show("slow");
	});	

	$(".dropdown-toggle").on("mouseleave", function () {
		$(".dropdown-menu").stop().hide("slow");
	});	
});
ul.navbar-header {
  margin-bottom:0; 
  height:50px;
}
ul.navbar-header > li, ul.navbar-header > li > a {
  height:50px;
}
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navbar navbar-inverse" role="navigation">
  <ul class="navbar-header list-inline"> 
    <li class="dropdown-toggle"><a href="#" class="navbar-brand" data-toggle="dropdown">Menu 1 </a>
      <ul class="dropdown-menu">
        <li><a href="#">Action</a></li>
        <li><a href="#">Another action</a></li>
        <li><a href="#">Something else here</a></li>
        <li><a href="#">Separated link</a></li>
      </ul>
    </li>
    <li><a href="#" class="navbar-brand"> Menu 2</a></li>
    <li><a href="#" class="navbar-brand"> Menu 3</a></li>
    <li><a href="#" class="navbar-brand"> Menu 4</a></li>
  </ul> 
</nav>
    
answered by 13.07.2016 в 00:21
1

Although Alvaro's answer is very good, I wanted to test if it was possible to make it work with the html code that you have, and I arrived at this solution using a mixture of hover() for the first level of the menu and mouseleave() for the submenu, I also had to change the bootstrap version to 3.3.6 and eliminate the margin of the submenu to be able to do the verification of hoverOut.

How does it work?

  • When you hover your mouse over the menu item, it displays the submenu.
  • When the mouse 'exits' from that menu item, find out if the next element with class dropdown-menu (or a submenu in this case) has the mouse on top or not (hover), otherwise it hides the submenu.
  • When the mouse 'leaves' the submenu, find out if the previous element is hover (according to the code layout, it is equivalent to the top menu), otherwise it hides the submenu.

$( ".dropdown-toggle" ).hover(
  function() {
    // hover in
    $( this ).next('.dropdown-menu').show("slow");
  }, function() {
    // hover out
    var menuHover = !$(this).next(".dropdown-menu").is(":hover");
    if (menuHover) {
      $( this ).next('.dropdown-menu').hide("slow");     
    }
  }
);

$(".dropdown-menu").mouseleave(function () {
  if (!$(this).prev().is(":hover")) {
$(this).hide("slow");
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<style>
.dropdown-menu {
  margin: 0;
}
</style>
<nav class="navbar navbar-inverse" role="navigation">
       <div class="navbar-header"> 
            <a href="#" class="dropdown-toggle navbar-brand" data-toggle="dropdown">Menu 1 </a>
                        <ul class="dropdown-menu">
                            <li><a href="#">Action</a></li>
                            <li><a href="#">Another action</a></li>
                            <li><a href="#">Something else here</a></li>
                            <li><a href="#">Separated link</a></li>
                        </ul>
            <a href="#" class="navbar-brand"> Menu 2</a>
            <a href="#" class="navbar-brand"> Menu 3</a>
            <a href="#" class="navbar-brand"> Menu 4</a>
       </div> 
</nav>
    
answered by 12.07.2016 в 21:40