问题描述
|
我有主导航和子导航,出于设计原因,它们位于单独的DIV中。我想在悬停主导航项时显示合适的子导航,但是我也想让子导航保持打开状态,如果用户将鼠标移到主导航项之外并进入子导航-导航区域。最后一部分是我被卡住的地方。
我正在考虑将鼠标悬停在上面,我需要使用setTimeout()和IF语句来做一些事情,但是在那方面我还没有取得任何进展。这甚至是值得尝试的方法吗?
HTML:
<div id=\"mnav\">
<ul id=\"buttons\">
<li class=\"one\"><a href=\"#\">Main 1</a></li>
<li class=\"two\"><a href=\"#\">Main 2</a></li>
<li class=\"three\"><a href=\"#\">Main 3</a></li>
<li class=\"four nav-dark\"><a href=\"#\">Main 4</a></li>
</ul>
</div> <!-- /mnav -->
<div id=\"snav\">
<ul class=\"snav-one\">
<li><a href=\"#\">Sub 1.1</a></li>
<li><a href=\"#\">Sub 1.2</a></li>
<li><a href=\"#\">Sub 1.3</a></li>
<li><a href=\"#\">Sub 1.4</a></li>
<li><a href=\"#\">Sub 1.5</a></li>
<li><a href=\"#\">Sub 1.6</a></li>
</ul>
<ul class=\"snav-two\">
<li><a href=\"#\">Sub 2.1</a></li>
<li><a href=\"#\">Sub 2.2</a></li>
</ul>
</div> <!-- /snav -->
JS:
$(document).ready(function() {
$(\"#buttons li.one,#buttons li.two\").hover(function(){
var subnav = \'ul.snav-\' + $(this).attr(\'class\');
$(\"#snav\").slideDown(\'fast\').addClass(\"open\").find(subnav).show();
},function(e){
var subnav = \'ul.snav-\' + $(this).attr(\'class\');
$(\"#snav\").slideUp(\'fast\').removeClass(\"open\").find(subnav).hide();
});
});
解决方法
对于鼠标菜单人体工程学,在从主菜单移至子菜单时需要一个小的延迟,因此子菜单不会在鼠标到达那里之前关闭。 (如问题所述。)
但是,您还需要在菜单打开之前有一定的延迟-既避免烦人的“飞越”激活,又可以减少在离开主菜单时意外从sub1切换到sub2的常见情况。
因此,问题代码需要:
子菜单
ul
元素上的hover
。
mouse4ѭ如果鼠标选择发生变化,则停止正在运行的动画。
一个可重置计时器,同时控制打开和关闭。
请参阅jsFiddle上的演示。
放在一起:
$(\"#buttons li.one,#buttons li.two\").hover ( function () { MenuOpenCloseErgoTimer (
100,function (node) {
var subnav = \'ul.snav-\' + $(node).attr (\'class\');
$(\"#snav ul\").hide ();
$(\"#snav\").stop (true,true).slideDown (\'fast\').addClass (\"open\").find (subnav).show ();
},this
); },function () { MenuOpenCloseErgoTimer (
200,function () {
$(\"#snav\").stop (true,true).slideUp (\'fast\').removeClass (\"open\").find (\'ul\').hide ();
}
); }
);
$(\"div#snav ul\").hover ( function () { MenuOpenCloseErgoTimer (
0,true).slideDown (\'fast\').addClass (\"open\");
$(this).show ();
}
); },true).slideUp (\'fast\').removeClass (\"open\");
$(\"#snav ul\").hide ();
}
); }
);
function MenuOpenCloseErgoTimer (dDelay,fActionFunction,node) {
if (typeof this.delayTimer == \"number\") {
clearTimeout (this.delayTimer);
this.delayTimer = \'\';
}
if (node)
this.delayTimer = setTimeout (function() { fActionFunction (node); },dDelay);
else
this.delayTimer = setTimeout (function() { fActionFunction (); },dDelay);
}
请注意ѭ6上要求的额外操作,以在子菜单之间的中断交换后清除。
,代替使用.hover()方法,尝试对mouseenter和mouseleave使用单独的事件处理程序。 mouseenter将仅附加到mnav按钮,而mouseleave将同时附加到mnav按钮和snav div。在mouseleave函数上,您可能不得不添加一个小的超时,并检查它们是否从一个元素移到另一个元素。
尝试这样的事情:
<script>
var timer;
$(document).ready(function() {
$(\"#mnav\").mouseenter(function() {
$(\"#snav\").slideDown();
});
$(\"#mnav,#snav\").mouseleave(function() {
timer=setTimeout(\"$(\'#snav\').slideUp();\",50);
});
$(\"#mnav,#snav\").mouseenter(function() {
clearTimeout(timer);
});
});
</script>
,参见示例→
以下应为您工作,我进行了一些更改:
使用.stop()
方法在进入子导航时暂停动画
将幻灯片移动到subnav ul的位置而不是容器,因此上述操作可行
其他一些事情
见下文:
$(\"#buttons li.one,#buttons li.two\").hover(function() {
var subnav = \'ul.snav-\' + $(this).attr(\'class\');
$(\"#snav\").find(\'ul\').slideUp(\'fast\');
$(\"#snav\").addClass(\"open\").find(subnav).stop(true,true).slideDown(\'fast\');
},function(e) {
var subnav = \'ul.snav-\' + $(this).attr(\'class\');
$(\"#snav\").removeClass(\"open\").find(subnav).slideUp(\'fast\');
});
$(\'#snav\').bind(\'mouseenter\',function(e) {
$(this).find(\'ul\').stop(true,false);
}).bind(\'mouseleave\',true).slideUp(\'fast\');
});
参见示例→