skip to Main Content

Trying to get it so when I hover over issues tab, a sub-menu drops, and when you leave the tab it disappears.That part works, however, when user hovers over the sub-menu I want it to remain. That is the part that is not working, it disappears right away even though the set timeout function is set to 3 seconds. I have no idea why it does that.

let timeout;

$('nav > ul li:first-child').on('mouseenter click', function () {
        if ($('.issues').css('display') == 'none') {
            $('.issues').slideDown('slow'); 
        }
        else {
            $('.issues').slideUp();
        } 
        }).on('mouseleave', function () {
            timeout = setTimeout(function () {
                $('.issues').slideUp();
            }, 3000);
        });

    $('.issues').mouseenter(function() {
        clearTimeout(timeout);
    });
.issues {
    display: none;
    position: static;
    margin-top: 0;
    padding-left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
                <li><a>Issues</a></li>
                <ul class="issues">
                    <li><a>X</a></li>
                    <li><a>Y</a></li>
                    <li><a>Z</a></li>
                </ul>
                <li><a>Press Releases</a></li>
                <li><a>Donate</a></li>
        </ul>
</nav>

2

Answers


  1. The UL should to be in the LI to be valid HTML. With that you have zero need for the sub menu to cancel the timeout since the mouse has not left the LI

    let timeout;
    
    $('nav > ul li:has(ul)').on('mouseenter click', function() {
      window.clearTimeout(timeout);
      if ($('.issues').css('display') == 'none') {
        $('.issues').slideDown('slow');
      } else {
        $('.issues').slideUp();
      }
    }).on('mouseleave', function() {
      timeout = setTimeout(function() {
        $('.issues').slideUp();
      }, 3000);
    });
    .issues {
      display: none;
      position: static;
      margin-top: 0;
      padding-left: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <nav>
      <ul>
        <li><a>Issues</a>
          <ul class="issues">
            <li><a>X</a></li>
            <li><a>Y</a></li>
            <li><a>Z</a></li>
          </ul>
        </li>
        <li><a>Press Releases</a></li>
        <li><a>Donate</a></li>
      </ul>
    </nav>
    Login or Signup to reply.
  2. For simplicity, I’d do something like this:

    $('nav > ul > li:first-child').on('mouseenter mouseleave click', function(ev) {
      const isHidden = $('.issues').css('display') == 'none';
    
      switch (ev.type) {
        case 'click':
          if (isHidden) {
            $('.issues').slideDown('slow');
          } else {
            $('.issues').slideUp();
          }
          break;
    
        case 'mouseleave':
          if (!isHidden) {
            $('.issues').slideUp();
          }
          break;
    
        case 'mouseenter':
          if (isHidden) {
            $('.issues').slideDown();
          }
          break;
    
        default:
          // Do nothing
          break;
      }
    });
    
    .issues {
      display: none;
      position: static;
      margin-top: 0;
      padding-left: 0;
    }
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <nav>
      <ul>
        <li>
          <a>Issues</a>
          <ul class="issues">
            <li><a>X</a></li>
            <li><a>Y</a></li>
            <li><a>Z</a></li>
          </ul>
        </li>
        <li><a>Press Releases</a></li>
        <li><a>Donate</a></li>
      </ul>
    </nav>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search