1

所以 jQuery 和setTimeOut正在躲避我!我呼吁 Stack 社区的善良性质寻求帮助。

我正在创建一个定制的下拉导航,并setTimeOut在脚本中实现了一些问题,因此菜单的响应超时。

我将详细介绍超时。

菜单需要有一个超时时间,mouseenter这样用户可能会不小心将鼠标悬停在链接上而不会触发下拉菜单;目前设置为 400 毫秒。我还想要一个超时,允许用户mouseleave下拉并在下拉隐藏之前有 1000 毫秒的时间悬停回下拉。

需要注意的是,将超时设置为阻止下拉菜单在下拉菜单之间无缝切换而不会闪烁。

如果一个下拉菜单可见并且用户将鼠标移动到另一个顶级链接(父级,即“服务”),则下拉菜单(其容器)的视觉效果会显示并且只有下拉菜单中的数据会发生变化。

我希望这涵盖了脚本的要求,如果没有,请让我详细说明。

JSfiddle 链接:http: //jsfiddle.net/ATqqv/8/

对于无法访问 JSfiddle 站点的纯粹主义者或窥视者,这里是我的 JS 代码。

function responsive_navigation() {
    var hover, $this;

    $target = $("header nav > ul > li");

    $target.on('mouseenter click', function (e) {
        $this = $(this);

        if(hover) {
            clearTimeout(hover); // Cancel the timeout to hide the menu
            hover = null;
        }

        hover = setTimeout(nav_show, 400);

    }).on('mouseleave', function () {
        //clearTimeout(hover);
        //hover = setTimeout(nav_hide, 1000);
        nav_hide();
    });

    // Show the menu relative to user actions
    function nav_show() {
        $this.addClass('active');
        $this.children('.dropnav').show();
    }
    // Hide the menu relative to user actions
    function nav_hide() {
        $this.children('.dropnav').hide();
        $this.removeClass('active');
    }
}

$(document).ready(function () {
    responsive_navigation();
});

预先感谢您提供任何帮助并为答案做出贡献。

4

2 回答 2

1

http://jsfiddle.net/DA4cv/8/

function responsive_navigation() {

var menuItems = $('header nav > ul > li');
var dropDowns = $('.dropnav');
var showTimer = null;
var hideTimer = null;

// hover over nav li
menuItems.on('mouseover click', function(){ 

    clearTimeout(showTimer);           
    clearTimeout(hideTimer);

    var mi = $(this);
    showTimer = setTimeout(function(){nav_show(mi);}, 400);
    menuItems.removeClass('active');
});

// end hover on nav li
menuItems.on('mouseleave', function(){

    clearTimeout(hideTimer);

    var mi = $(this);
    hideTimer = setTimeout(function(){nav_hide(mi);}, 1000);
});

// hover over dropdown
dropDowns.on('mouseover', function(){
    clearTimeout(hideTimer);
});

// end hover on dropdown
dropDowns.on('mouseleave', function(){
    var dd = $(this);
    hideTimer = setTimeout(function(){nav_hide(dd.parent());}, 1000);    
}); 

// Show the menu relative to user actions
function nav_show(menuItem) {
    dropDowns.hide();
    $(menuItem).children('.dropnav').show();
    $(menuItem).addClass('active');
}

// Hide the menu relative to user actions
function nav_hide(menuItem) {
    menuItem.children('.dropnav').hide();
    menuItem.removeClass('active');
}  

}

$(document).ready(function () {
    responsive_navigation();
});
于 2013-08-08T12:24:16.127 回答
1

这里的关键是管理你的延迟执行。

在这些事件中,我确保我取消任何即将发生的相反的相反动作。如果当前操作尚未迫在眉睫,并且是必要的,那么我将启动将调用适当 ui 函数的计时器。

我清除了ui函数的所有超时,以防它们以事件以外的其他方式被调用。如果这不是问题,您可以删除任何实例,cancelAction()并在显示另一个菜单时停止活动菜单的隐藏操作。

var $parent = $("header nav > ul");

$parent.children('li').on('mouseenter click', function (e) {
    var $this = $(this);
    // cancel hiding if we left and cameback in time
    cancelAction($this, 'hover_hide_to'); 
    if (!actionImpending($this, 'hover_show_to') && !$this.hasClass('active')) {
        $this.data('hover_show_to', setTimeout(function() { nav_show($this); }, 400));
    }
}).on('mouseleave', function () {
    var $this = $(this);
    cancelAction($this, 'hover_show_to');
    if (!actionImpending($this, 'hover_hide_to') && $this.hasClass('active')) {
        $this.data('hover_hide_to', setTimeout(function() { nav_hide($this); }, 1000));
    }
});

// returnts the impending action timer id.
function actionImpending($elem, name) {
    return $elem.data(name);
}

// clear timeout for element
function cancelAction($elem, name) {
    clearTimeout($elem.data(name));
    $elem.data(name, 0);
}

function cancelAllActions($elem) {
    cancelAction($elem, 'hover_show_to');
    cancelAction($elem, 'hover_hide_to');  
}

// Show the menu, hiding the active menu.
function nav_show($elem) {
    cancelAllActions($elem);
    var $active = $parent.children(".active");
    if ($active.length > 0) {
        nav_hide($active);
    }
    $elem.addClass('active').children('.dropnav').show();
}

// Hide the menu
function nav_hide($elem, delay) {
    cancelAllActions($elem);        
    $elem.removeClass('active');
    $elem.children('.dropnav').hide();
}

jsFiddle

于 2013-08-08T22:33:44.703 回答