Search code examples
javascriptjqueryhtmlhoverintent

jQuery Hover Intent, sub menu disappears / buggy when interval is greater than 0


I am currently using the jQuery Hover Intent plugin to add an initial delay when triggering the hover of a menu.

HTML:

<div>
    <ul>
        <li class="link hover"><a href="#">Hover</a></li>
    </ul>
</div>

<div class="sub hover">
     <h1>Sub Section</h1>
</div>

JS:

// Vars
var timeout;

// Show Menu
function showMenu() {
    clearTimeout(timeout);
    $('.sub').fadeIn(50);
}

// Hide Menu
function hideMenu() {
    timeout = setTimeout(function () {
        $('.sub').fadeOut(50);
    }, 100);
}

// Settings
var config = {
    interval: 50, // time between reading/comparing mouse coordinates
    timeout: timeout, // time before out function is called
    over: showMenu,
    out: hideMenu
};

// Initialise Hover
$('.hover').hoverIntent(config);

In the config, when the interval is set to 0 switching between the containers works fine.

When i set the interval greater than 0 hovering in and out of the containers becomes buggy (sub menu flickers and disappears). However i need the interval set for the initial delay.

JS Fiddle: http://jsfiddle.net/hfx7ucnw/4/


Solution

  • EDIT - new answer

    OK mate. If you has this html and you can't change that try to .stop(true) the fadeOut animation every time you trigger mouseenter or over to prevent the fadeOut.

    I don't know if this is possibile with hoverIntent plugin, but you can use this code instead:

    $(".hover").on({
        "mouseenter" : function(e){
            $(".sub").stop(true);
            $(".sub").fadeIn();
        },
        "mouseleave" : function(e){
            $(".sub").delay(50).fadeOut();
        },
    })
    

    EDIT #2 - PREVENT ACCIDENTALLY OVER

    To prevent accidentally over simple add a delay to the fadeIn effect if user is "over" the .hover button (but not when is over .sub).

    And also in mouseleave add .stop(true) to prevent the fadeIn on "fast moving":

    $(".hover,.sub").on({
        "mouseenter" : function(e){
            _delay = ($(this).hasClass("hover")) ? 200 : 0 ;
            $(".sub").stop(true);
            $(".sub").delay(_delay).fadeIn();
        },
        "mouseleave" : function(e){
            $(".sub").stop(true);
            $(".sub").delay(50).fadeOut();
        },
    })
    

    Work with delay and fadeIn time to create the best performance.

    EXAMPLE: http://jsfiddle.net/hfx7ucnw/8/

    OLD answer

    It's a problem that I know.

    From my experience I can tell you that the only way to create a "dropdown" or a "submenu" that show on mouseover and hide on mouseleave is to indent the child element to parent I edit Your fiddle to show you my way.

    with some simple change on CSS and HTML

    http://jsfiddle.net/hfx7ucnw/5/

    Tell me if this way is your.