我目前正在使用一些javascript来侦听id为#drop-nav-trigger
的导航元素上的mouseenter。这个想法是,如果他们没有悬停超过250毫秒,那么元素下拉菜单不会激活。如果用户只是将鼠标移到元素上以到达页面上的其他位置,我想阻止它显示。它很棒!
但是现在我想对同一导航菜单中的两个或更多元素做同样的事情(但不是所有元素)。我该如何处理?我是否只是为每个想要拥有此功能的导航项复制我的javascript?或者有没有办法将它们整合到一个代码片段中?
以下是我的HTML示例。在这个例子中,我想让javascript观看mouseenter的前两个顶级元素,但忽略第三个元素。我认为has-submenu
将是我需要注意的。
<ul class="main-nav-wrapper">
<li id="drop-nav-trigger" class="nav-item has-submenu">
Browse Products
<div class="submenu">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
</div>
</li>
<li class="nav-item has-submenu">
Second Top Level Item
<div class="submenu">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
</div>
</li>
<li class="nav-item">
Third Top Level Item
</li>
</ul>
这是我的javascript。我也在那里使用一些jQuery来将active
类添加到导航项。一旦脚本将active
添加到元素,我就使用CSS来显示隐藏的子菜单。
我认为我的问题是,与侦听ID不同,我的类在多个元素之间共享。因此,如果我倾听它,我将最终将active
添加到我的所有匹配元素中。
var timeoutId = null;
var el = document.getElementById("drop-nav-trigger");
/* Activate menu after a delay. */
if(el) {
el.addEventListener('mouseenter',function() {
timeoutId = window.setTimeout(function(){
$("#drop-nav-trigger").addClass("active");
}, 250);
} );
// Cancel your action if mouse moved out within 2 sec
el.addEventListener('mouseleave',function() {
window.clearTimeout(timeoutId);
$("#drop-nav-trigger").removeClass("active");
});
}
答案 0 :(得分:2)
您可以使用jQuery的hover
功能,该功能接受两个回调 - 一个用于mouseenter
,一个用于mouseleave
。我们在所有.has-submenu
项上使用此功能。您担心将.active
添加到所有匹配的子项中 - 在回调函数中,jQuery将实际元素作为this
传递,因此我们可以使用它来确保我们只将它添加到正确的元素:< / p>
$('.has-submenu').hover(function() {
//mouseenter callback
//keep separate reference to this so we can use it in the timeout function
var li = this;
$(li).data('timeoutId', setTimeout(function() {
$(li).addClass('active');
}, 250));
}, function() {
//mouseleave callback
clearTimeout($(this).data('timeoutId'));
$(this).removeClass('active');
});
此外,我使用data
函数将计时器ID存储在每个单独的元素上,这样它们就不会相互干扰,同时也消除了对{{{3}}的需求。 1}}变量超出了这些函数的范围。