tomp4
tomp4

Reputation: 3

jQuery lenght doesn't work in firefox

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>
             <!--...-->   

Upvotes: 0

Views: 71

Answers (1)

Daniel Beck
Daniel Beck

Reputation: 21505

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>

Upvotes: 1

Related Questions