2010-05-19 141 views
99

所以我有一個下拉菜單,根據業務需求點擊顯示。鼠標遠離後,菜單會再次隱藏。點擊外部菜單關閉jquery

但是現在我被要求讓它保持原狀,直到用戶點擊文檔上的任何位置。這如何實現?

這是什麼,我現在有一個簡化版本:

$(document).ready(function() { 
    $("ul.opMenu li").click(function(){ 
    $('#MainOptSubMenu',this).css('visibility', 'visible'); 
    }); 

    $("ul.opMenu li").mouseleave(function(){ 
     $('#MainOptSubMenu',this).css('visibility', 'hidden'); 
    }); 
}); 



<ul class="opMenu"> 
    <li id="footwo" class=""> 
    <span id="optImg" style="display: inline-block;"> <img src="http://localhost.vmsinfo.com:8002/insight/images/options-hover2.gif"/> </span> 
     <ul id="MainOptSubMenu" style="visibility: hidden; top: 25px; border-top: 0px solid rgb(217, 228, 250); background-color: rgb(217, 228, 250); padding-bottom: 15px;"> 
     <li>some</li> 
     <li>nav</li> 
     <li>links</li> 
     </ul> 
    </li> 
</ul> 

我想是這樣的$('document[id!=MainOptSubMenu]').click(function()以爲它會觸發任何wasnt菜單,但它沒有工作。

+0

我在這裏有一個答案。 > [http:// stackoverflow。COM /問題/ 152975 /怎麼辦 - 我 - 檢測 - 一鍵式外一元/ 43405204#43405204(http://stackoverflow.com/questions/152975/how-do-i-detect-a -click-outside-an-element/43405204#43405204) – 2017-04-14 04:29:55

+0

可能重複[如何檢測元素外部的點擊?](http://stackoverflow.com/questions/152975/how-do-i-detect- a-click-an-element) – 2017-04-14 12:11:26

回答

182

看一看的方法中使用這樣的問題:

How do I detect a click outside an element?

附上一個click事件文檔正文其關閉窗口。將一個單獨的點擊事件附加到停止傳播到文檔主體的窗口。
$('html').click(function() { 
    //Hide the menus if visible 
}); 

$('#menucontainer').click(function(event){ 
    event.stopPropagation(); 
}); 

+13

它非常美麗,但你應該使用$('html')。click()不是body。身體總是具有其內容的高度。它沒有太多的內容,或者屏幕非常高,只能在身體填充的部分工作。複製從:http://stackoverflow.com/questions/152975/how-to-detect-a-click-outside-an-element - meo Feb 2 25 '11在15:35 – NickGreen 2012-01-20 12:50:22

+0

偉大的解決方案。任何想法爲什麼它與.click(),而不是與.live('click',func ...? – Hat 2013-04-18 00:41:46

+3

)一起工作?這種方法唯一的問題是,已經有一個點擊監聽器的對象,其中stopPropagation由於其他原因沒有效果。我理解爲什麼它是這樣的,但它仍然是這個解決方案的一個侷限性。 – DanH 2013-05-14 02:58:39

7

2,你可以調查選項:

  • 在菜單的顯示,放置一個大的空DIV背後卻掩蓋了頁面的其餘部分並給予一對點擊事件關閉菜單(及其本身)。這與用於單擊背景的Lightbox關聯的方法類似,可以在關閉菜單的主體上附加一次性單擊事件處理程序。你使用jQuery的'.one()'。
+0

謝謝!我正在Wordpress網站上工作,並且第一個解決方案適用於我! – 2017-01-25 03:20:30

16

如果使用插件在你的情況下確定,那麼我建議本Alman的clickoutside插件位於here

它的使用是如此簡單:

$('#menu').bind('clickoutside', function (event) { 
    $(this).hide(); 
}); 

希望這會有所幫助。

+1

這個插件非常輕巧實用,易於實現。感謝分享鏈接。 – 2015-02-06 00:32:00

+0

偉大的插件,一直沒有更新,但仍然很好。 – uberweb 2015-02-12 03:49:01

1

我想你需要的東西是這樣的:http://jsfiddle.net/BeenYoung/BXaqW/3/

$(document).ready(function() { 
    $("ul.opMenu li").each(function(){ 
     $(this).click(function(){ 
      if($(this).hasClass('opened')==false){   
       $('.opMenu').find('.opened').removeClass('opened').find('ul').slideUp(); 
       $(this).addClass('opened'); 
       $(this).find("ul").slideDown(); 
      }else{ 
       $(this).removeClass('opened'); 
       $(this).find("ul").slideUp();    
      } 
     }); 
    });  
}); 

我希望對您有用!

48

答案是對的,但它會添加一個偵聽器,每次在您的頁面上發生點擊時都會觸發該偵聽器。爲了避免這種情況,您可以添加監聽器只是一個時間:

$('a#menu-link').on('click', function(e) { 
    e.preventDefault(); 
    e.stopPropagation(); 

    $('#menu').toggleClass('open'); 

    $(document).one('click', function closeMenu (e){ 
     if($('#menu').has(e.target).length === 0){ 
      $('#menu').removeClass('open'); 
     } else { 
      $(document).one('click', closeMenu); 
     } 
    }); 
}); 

編輯:如果你想避免stopPropagation()初始按鈕,您可以使用此

var $menu = $('#menu'); 

$('a#menu-link').on('click', function(e) { 
    e.preventDefault(); 

    if (!$menu.hasClass('active')) { 
     $menu.addClass('active'); 

     $(document).one('click', function closeTooltip(e) { 
      if ($menu.has(e.target).length === 0 && $('a#menu-link').has(e.target).length === 0) { 
       $menu.removeClass('active'); 
      } else if ($menu.hasClass('active')) { 
       $(document).one('click', closeTooltip); 
      } 
     }); 
    } else { 
     $menu.removeClass('active'); 
    } 
}); 
+0

我看到這樣的代碼很多,這不會爲每次菜單鏈接添加一個新的點擊功能的文檔點擊了嗎?所以如果你單擊菜單鏈接1000次而不刷新頁面,你將有1000個函數佔用內存並執行? – eselk 2013-04-08 22:10:56

+0

沒關係,我沒有看到「one」函數,現在我明白了爲什麼這樣工作:http://api.jquery.com/one/ – eselk 2013-04-08 22:15:20

+2

不錯的解決方案,但我不得不在Chrome中使用'e.stopPropagation()'來阻止第一個事件在'one()處理器 – antfx 2015-06-10 19:45:44

4

這個怎麼樣?

$(this).mouseleave(function(){ 
     var thisUI = $(this); 
     $('html').click(function(){ 
       thisUI.hide(); 
      $('html').unbind('click'); 
     }); 
    }); 
2

即使我遇到了同樣的情況,我的導師之一把這個想法傳達給自己。

step:1點擊了我們應該顯示下拉菜單的按鈕。然後添加以下類名「more_wrap_background」到當前活動頁面像下面

$('.ui-page-active').append("<div class='more_wrap_background' id='more-wrap-bg'> </div>"); 

步驟-2然後添加一個點擊次數div標籤等

$(document).on('click', '#more-wrap-bg', hideDropDown); 

示出,其中hideDropDown是函數被調用來隱藏下拉菜單

第3步和隱藏下拉菜單的重要步驟是,刪除您以前添加的類如

$('#more-wrap-bg').remove(); 

我在上面的代碼

.more_wrap_background { 
    top: 0; 
    padding: 0; 
    margin: 0; 
    background: rgba(0, 0, 0, 0.1); 
    position: fixed; 
    display: block; 
    width: 100% !important; 
    z-index: 999;//should be one less than the drop down menu's z-index 
    height: 100% !important; 
} 
3

使用ID刪除我發現Grsmto's solution變體和Dennis' solution固定我的問題。

$(".MainNavContainer").click(function (event) { 
    //event.preventDefault(); // Might cause problems depending on implementation 
    event.stopPropagation(); 

    $(document).one('click', function (e) { 
     if(!$(e.target).is('.MainNavContainer')) { 
      // code to hide menus 
     } 
    }); 
}); 
2
$("html").click(onOutsideClick); 
onOutsideClick = function(e) 
{ 
    var t = $(e.target); 
    if (!(
     t.is("#mymenu") ||  //Where #mymenu - is a div container of your menu 
     t.parents("#mymenu").length > 0 
     ) ) 
    { 
     //TODO: hide your menu 
    } 
}; 

,更好地設定只有當你的菜單是可見的,並隨時刪除監聽器菜單被隱藏後的監聽器。

3

我覺得使用mousedown事件而不是點擊事件更有用。如果用戶使用點擊事件點擊頁面上的其他元素,則點擊事件不起作用。在與jQuery的一個()方法的組合,它看起來是這樣的:

$("ul.opMenu li").click(function(event){ 

    //event.stopPropagation(); not required any more 
    $('#MainOptSubMenu').show(); 

    // add one mousedown event to html 
    $('html').one('mousedown', function(){ 
     $('#MainOptSubMenu').hide(); 
    }); 
}); 

// mousedown must not be triggered inside menu 
$("ul.opMenu li").bind('mousedown', function(evt){ 
    evt.stopPropagation(); 
}); 
4

我用具有相同行爲的多個元素在同一個頁面此解決方案:

$("html").click(function(event){ 
    var otarget = $(event.target); 
    if (!otarget.parents('#id_of element').length && otarget.attr('id')!="id_of element" && !otarget.parents('#id_of_activator').length) { 
     $('#id_of element').hide(); 
    } 
}); 

stopPropagation()是一個壞主意,這打破了很多事情的標準行爲,包括按鈕和鏈接。

+0

這很棒,但可以簡化爲'$ target.closest('#menu-container,#menu-activator')。length === 0' – 2014-06-19 19:43:23

12

stopPropagation選項不好,因爲它們可能會干擾其他事件處理程序,包括其他可能附加了html元素的處理程序的菜單。

這是基於user2989143的回答一個簡單的解決方案:

$("html").click(function(event) { 
    if ($(event.target).closest('#menu-container, #menu-activator').length === 0) { 
     $('#menu-container').hide(); 
    } 
}); 
1

使用 ':可見' 選擇。 凡.menuitem是要隱藏元素(S)...

$('body').click(function(){ 
    $('.menuitem:visible').hide('fast'); 
}); 

或者,如果你已經有了一個變種的.menuitem元素(S)...

var menitems = $('.menuitem'); 
$('body').click(function(){ 
    menuitems.filter(':visible').hide('fast'); 
}); 
4

我有最近面臨同樣的問題。我寫了下面的代碼:

$('html').click(function(e) { 
     var a = e.target; 
     if ($(a).parents('.menu_container').length === 0) { 
     $('.ofSubLevelLinks').removeClass('active'); //hide menu item 
     $('.menu_container li > img').hide(); //hide dropdown image, if any 
    } 
    }); 

它對我來說是完美的。