jQuery slideToggle菜单基于mouseenter / leave

时间:2014-03-05 19:25:03

标签: javascript jquery

我主要有一个小菜单系统工作,但有几个怪癖我无法弄清楚。在同样的问题上我似乎没有任何问题。

功能示例位于http://louisnk.com/photography - 唯一具有相当代码的菜单是' USA'。

点击,菜单显示,我希望它:

  • A)延迟,如果mouseenter事件永远不会触发,则向后滑动

    B)如果mouseenter事件触发,则不会向上滑动

    C)延迟,然后在鼠标离开时向上滑动

我很清楚,除了我相信我有一些事件授权问题......

我第一次点击,一切都很棒。我第二次点击任何一个菜单,似乎都是“捅了一下”。 (根据开关情况设置为true / false的变量)被设置为false,因此自动导致“noPoke”#39;无论mouseenter事件如何,都可以关闭菜单。随后的点击显然会导致陌生人的行为。

我将以下代码全部包含在文档就绪函数中:

var menuSwitch = function(menu) {
    $(menu).on('mouseenter mouseleave', function(e) {

        switch(e.type) {

            case 'mouseenter':
                poked = true;
                console.log('probed');
                return false;
                break;

            case 'mouseleave':

                $(this).delay(1500).slideUp(500,function() {
                    $(menu + 'li').hide();
                    console.log('switched');
                });                 
                poked = false;
                break;

            default:
                poked = false;
                console.log('defaulting');
                break;
        }
    });
}

var noPoke = function(menu) {
    if (poked == false) {
        $(menu).delay(2000).slideUp(500,function() {
            $(menu + 'ul').hide();
            console.log('no pokes given');
        });
        poked = true;
    }
}

var poked = false;

$('.usa').click(function(e) {
    e.preventDefault();

    poked = false;      

    $('.usaMenu').slideToggle(500);

    menuSwitch('.usaMenu');

    console.log(poked);

 $('.usaMenu li').on('mouseenter', function() {
        if ($(this).children() != false) {
            $(this).children().fadeTo(200,1);
        }
        else {
            $('.usaMenu li>ul').fadeTo(200,0).hide();
        }
    });

    noPoke('.usaMenu');

});

1 个答案:

答案 0 :(得分:0)

所以,经过另外6个小时的研究和尝试不同的事情,我最终得到了以下内容,这解决了我遇到的问题。

希望这对将来尝试这样做的人有用。

var menuSwitch = function(menu) {

    if ($(menu).is(':hover') === false) {
        var hideMe = setTimeout(function() {
            $(menu).slideToggle(500);
        },4000);
    }

    $(menu).on('mouseenter mouseleave', function(e) {

        switch(e.type) {

            case 'mouseenter':

                console.log('probed');
                clearTimeout(hideMe);
                $(this).stop();
                $(this).slideDown(200);
                break;

            case 'mouseleave':

                $(this).delay(2000).slideUp(500,function() {
                    $('li>ul',menu).hide();
                    console.log('switched');
                });                 
                break;
        }
    });
}


var babies = function(menu) {
    $('li',menu).unbind('mouseenter mouseleave click');

    $('li',menu).each(function() {
        if ($('li',menu).children() != false) {

            $(this).on('click',function(e) {
                e.preventDefault();
                $(this).children('ul').slideToggle(300);                    
            });
        }
    });

}


var menuCtrl = function(menu) {
    $(menu).slideToggle(500);

    $(menu).unbind('mouseenter mouseleave');

    menuSwitch(menu);

    babies(menu);
}


$('.usa').click(function(e) {
    e.preventDefault(); 

    menuCtrl('.usaMenu');

});

最终事实证明,因为初始点击处理程序在每次触发时都运行了函数,所以它创建了mouseenter / leave事件处理程序的副本,因此导致了各种各样的问题。如果鼠标从未以错误的方式进入,我也试图让菜单关闭。

为了解决最讨厌的问题(重复的事件处理程序),我只使用了unbind()api,在函数的开头将事件传递给unbind,这样当它们被重新绑定时,只有一个实例。这可能不是最有效的方式,但它确实有效。

如果没有mouseenter问题解决时间/隐藏问题,我使用了setTimeout函数,如果是mouseenter-ed则会被清除。