2014-02-26 60 views
0

我試圖創建菜單,當鼠標懸停在菜單名稱上時,下拉菜單。由於名稱和菜單div不相鄰,我需要一種方法來延遲菜單消失,因此用戶可以從名稱移動到菜單本身。我爲此使用了setTimeout。一旦懸停在菜單上,我需要它保持打開狀態,直到鼠標離開,之後它應該隱藏。setTimeout/clearTimeout問題,似乎並沒有重置

我試過的是一個完整的混亂。不知道如何解決它。因爲setTimeout在初始的mouseover內部,所以定時器在自身上循環......但是如果我把它放在其他地方,setTimeout似乎不起作用。

下面的代碼:

$(document).ready(function() { 
    $('.headermenushow').mouseover(function() { 
    $(this).next('.dropmenu').show(0, function() { 
     timer = setTimeout(function() { 
     $('.dropmenu').hide(10); 
     }, 2000); 
    }); 

    $(this).next('.dropmenu').mouseover(function() { 
     clearTimeout(timer); 
    }); 

    }); 
}); 

這裏是展示我要如何使用它的一個簡略的jsfiddle:

http://jsfiddle.net/H247x/1/

任何幫助將是巨大的。真的不知道如何得到這個工作更好...

+4

你可以爲我們提供的jsfiddle了點。 –

+0

我們需要查看您的HTML並更準確地瞭解您要完成的工作。就目前而言,很明顯,您當前的代碼存在很多錯誤,但不清楚您正在嘗試執行的操作。 – jfriend00

+0

增加了jsfiddle - 應該演示我如何使用這個 – user3180105

回答

5

有各種與此代碼的問題:

  1. 您要添加的.mouseover()事件中的事件處理程序。這意味着每次有一個鼠標懸停事件時,您都會添加另一組事件處理程序。當ALL執行時,這些會堆積起來並造成混亂。每個活動對象只需要一組事件處理程序。

  2. 你的整個邏輯應該如何工作似乎有缺陷。只要鼠標懸停在某個項目上,就希望菜單保持下降狀態。鼠標懸停事件只有在鼠標第一次移動到物品上時纔會發生。無論鼠標是否存在,您都無法在鼠標懸停在菜單上時保持菜單向下,因爲您似乎只在顯示後2秒時盲目隱藏菜單。

  3. 您正在爲您的計時器使用隱式全局變量。這造成了一堆問題。首先,如果有多個對象,則每個對象的對象timer都會踩在其他對象上。其次隱含的全局變量很糟糕,很容易導致錯誤。在您想要的範圍內明確聲明。

  4. 您可以在定時器之上定時器。無論何時將計時器保存到共享變量,都必須檢查之前已經運行的計時器,或者在覆蓋變量之前停止先前的計時器。這可以防止丟失正在運行的計時器的軌跡,並防止堆疊多個計時器,所有嘗試執行相同操作的計時器。

我們或許可以幫助你拿出更好的代碼,但我們需要看到實際的HTML和更好地瞭解究竟該行爲是什麼,你想實現。您可能還需要查看CSS :hover選擇器,該選擇器可讓您在懸停時顯示/隱藏任何JS代碼。由於我不知道你的HTML是什麼樣的,所以我不能確定這是否適用於你,但它被許多菜單系統使用。


既然您已經透露了您的HTML,這裏有一個可用的版本。我必須說,這個javascript很多是因爲你的HTML並不像它那樣容易。

$(document).ready(function() { 
    $(".headermenushow").hover(function() { 
     // hide any previous dropdown menus 
     $(".dropmenu").hide(); 

     var self = $(this); 
     var timer = self.data("timer"); 

     // show the dropdown menu for this item 
     self.next().show(); 

     // clear any previous timer for this menu 
     if (timer) { 
      clearTimeout(timer); 
      self.data("timer", null); 
     } 

    }, function() { 
     // hide only on a delay so that user can move 
     // to the menu 
     var self = $(this); 
     var menu = self.next(); 
     var timer = self.data("timer"); 
     // clear any previous timer that might have been active 
     if (timer) clearTimeout(timer); 
     timer = setTimeout(function() { 
      self.data("timer", null); 
      // if mouse is not over the menu, then hide it 
      if (!menu.data("hover")) { 
       menu.hide(); 
      } 
     }, 500); 
     self.data("timer", timer); 

    }); 

    // keep track of hover state on the menu 
    $(".dropmenu").hover(function() { 
     $(this).data("hover", true); 
    }, function() { 
     $(this).data("hover", false); 
     $(this).hide(); 
    }); 
}); 

工作演示:http://jsfiddle.net/jfriend00/YJu6Q/

+0

是的,我的腳本存在很多問題。我首先查看了CSS,但無法達到我需要的效果。關於第2點 - 我意識到這是一個問題,但setTimeout似乎不工作,除非我將它包含在原始事件中。 – user3180105

+0

嘗試在沒有setTimeout的情況下執行此操作 - 只使用延遲隱藏()和顯示() - 但無法使其正常工作。下面是這個例子:http://jsfiddle.net/H247x/2/ – user3180105

+0

這個概念已經在這個答案中得到了很好的解釋,所以我將這裏留下來:http://jsfiddle.net/H247x/4/ –

相關問題