0

I created the menu bar with rolldown menu. This short code should hide this rolldown menu (.rolldown-menu) and turn off the button (.rolldown-button) when mouse leaves the button with the exception when mouse is over the rolldown menu. All works fine with Chrome and Opera, but doesn't with FF and IE. In FF $(".rolldown-menu:hover").length is always 0. Can someone see something what I'm doing wrong?

$(".rolldown-button").mouseleave(function() {
    var hovered = $(".rolldown-menu:hover").length;
    if ( hovered > 0) {
    } else {
        $(".rolldown-menu").removeClass("active");
        $(".rolldown-button").removeClass("active");           
    }
});

The structure of html looks like this:

            <header class="head">
                <!--...-->
                <nav class="nav-bar">
                    <ul class="main-menu">
                        <li class="menu-item rolldown-button">
                            <a href="#">item 1</a>
                        </li>
                        <li class="menu-item">
                            <a href="#">item 2</a>
                        </li>
                        <li class="menu-item">
                            <a href="#">item 3</a>
                        </li>
                        <li class="menu-item active">
                            <a href="#">item 4</a>
                        </li>
                    </ul>      
                </nav>
            </header>

            <!--...-->

            <div class="rolldown-menu navbar-fixed-top hidden-xs">
                <div class="container">
                   <div class="row">
                        <div class="col-sm-3">
                            <ul>
                                <li class="menu-item active">
                                    <a href="#">submenu - items...</a>
                                </li>
             <!--...-->   
3
  • Hello and welcome. Could you add more of the code that is used particularly the html. You will need to give better description and code example(s) of what you have or trying, so others can assist you further. Commented Aug 9, 2017 at 22:35
  • Possible duplicate of Jquery condition check is(':hover') not working
    – Mr. Hugo
    Commented Aug 9, 2017 at 22:35
  • I've added the html.
    – tomp4
    Commented Aug 9, 2017 at 22:45

1 Answer 1

1

You're capturing the mouseleave of one element and simultaneously trying to test the hover of a different element.

I've tested Firefox, Chrome, and Safari, and they treat these situations differently: in Firefox, if the elements are adjacent, the mouseleave fires before the hover of the second element becomes true. (Interestingly, this is the case even if the menu is absolutely-positioned to overlap the button element!) Only if the elements are nested, with the button inside the menu, will the menu hover will be true when the button mouseleave fires.

In Safari and Chrome, mouseleave appears to fire a bit later, so the hover is true for the menu element in both test cases, so long as the adjacent elements have no gap between them.

$(".rolldown-button").mouseleave(function() {
  var hovered = $(".rolldown-menu:hover").length;
  console.log("Hovered is ", hovered);
});
.rolldown-button {width: 150px}
.rolldown-menu, .rolldown-button {border: 1px solid}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

This always returns 1 when mousing from button to menu:
<div class="rolldown-menu">
  <div class="rolldown-button">Button</div>
  Menu
</div>
<br><br>

This returns 1 in Safari and Chrome, but 0 in Firefox:

<div class="rolldown-button">Button 2</div>
<div class="rolldown-menu">Menu 2</div>

For this to work reliably, you'll either need to restructure your HTML so that the button is nested inside the menu, or else add a short delay after the mouseleave before testing .rolldown-menu:hover:

$(".rolldown-button").mouseleave(function() {
  window.setTimeout(function() {
  var hovered = $(".rolldown-menu:hover").length;
  console.log("Hovered is ", hovered);
  },10)
});
.rolldown-button {width: 150px}
.rolldown-menu, .rolldown-button {border: 1px solid}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="rolldown-button">Button 2</div>
<div class="rolldown-menu">Menu 2</div>

4
  • Great thinking and great find! +1
    – Mr. Hugo
    Commented Aug 9, 2017 at 22:47
  • Thank you! Lucky guess, really; I didn't expect it to be browser-specific but it does appear to be. Commented Aug 9, 2017 at 22:50
  • Thanks a lot Daniel! I've decided to leave it as it is for Chrome and make another behavor of that rolldown menu for FF and IE.
    – tomp4
    Commented Aug 10, 2017 at 8:14
  • @tomp4 I updated the answer to include a demonstration of the "add a short delay", which seems to work well; that might be better than coding different behavior for different browsers. Commented Aug 10, 2017 at 12:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.