2015-11-17 54 views
0

我正在使用一些javascript來偵聽id爲#drop-nav-trigger的導航元素上的mouseenter。這個想法是,如果他們沒有把鼠標懸停超過250ms,那麼元素下拉菜單不會被激活。我想阻止它顯示,如果用戶只是將鼠標移動到元素上以到達頁面上的其他位置。它很棒!在多個導航元素上有效使用addEventListener

但現在我想在同一個導航菜單(但不是所有的元素)中對兩個或更多元素做同樣的事情。我該如何處理?我是否爲每個導航項目重複我的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

你似乎在使用jQuery來添加和刪除類 - 你會對基於jQuery的解決方案感到滿意嗎? (這樣做可能會大大減少所需的代碼量) –

+0

當然,我完全可以用jQuery來解決這個問題。我相信如果我能夠使用$(this)它可以解決我的問題。但我不知道足夠的JavaScript來了解相應的內容。 – jkupczak

回答

2

您可以使用jQuery的hover功能,它接受兩個回調 - 一個用於mouseenter,一個用於mouseleave。我們在所有.has-submenu項目上使用此項。你擔心加入.active到所有匹配的子項 - 回調函數的jQuery通過實際的元素作爲this內,所以我們可以利用的,爲了確保我們只將它添加到正確的:

$('.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存儲在每個單獨的元素上,這樣它們就不會相互干擾,並且也不需要這些函數範圍外的變量。

相關問題