点击外部菜单closuresjquery
所以我有一个下拉菜单,按照业务需求点击显示。 鼠标远离后,菜单将再次隐藏。
但现在我被要求让它保持原状,直到用户点击文档上的任何地方。 这怎么能做到呢?
这是我现在所拥有的简化版本:
$(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/insighthttp://img.dovov.comoptions-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()
认为它会触发菜单上的任何东西,但它没有工作。
看看这个问题使用的方法:
如何检测元素外的点击?
将单击事件附加到closures窗口的文档主体。 将一个单独的单击事件附加到停止传播到文档主体的窗口。
$('html').click(function() { //Hide the menus if visible }); $('#menucontainer').click(function(event){ event.stopPropagation(); });
答案是对的,但是它会添加一个监听器,每次点击页面时都会触发。 为了避免这种情况,您可以添加侦听器一次:
$('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); } }); });
编辑:如果你想避免在初始buttonstopPropagation()
你可以使用这个
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'); } });
如果在你的情况下使用插件是可以的,那么我build议Ben Alman的clickout插件位于这里 :
其用法如此简单:
$('#menu').bind('clickoutside', function (event) { $(this).hide(); });
希望这可以帮助。
stopPropagation选项是不好的,因为它们可能会干扰其他事件处理程序,包括其他可能已经附加到html元素的处理程序的菜单。
这里是一个简单的解决scheme,基于user2989143的答案:
$("html").click(function(event) { if ($(event.target).closest('#menu-container, #menu-activator').length === 0) { $('#menu-container').hide(); } });
您可以调查的2个选项:
- 在显示菜单时,在它后面放置一个大的空DIV,以覆盖页面的其余部分,并给出一个点击事件来closures菜单(及其本身)。 这类似于在单击背景的Lightbox上使用的closuresLightbox的方法
- 在显示菜单时,在closures菜单的正文上附加一次单击事件处理程序。 你使用jQuery的“.one()”。
那这个呢?
$(this).mouseleave(function(){ var thisUI = $(this); $('html').click(function(){ thisUI.hide(); $('html').unbind('click'); }); });
我在同一页面中使用具有相同行为的多个元素的解决scheme:
$("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()是一个坏主意,这打破了很多事情的标准行为,包括button和链接。
我最近面临同样的问题。 我写了下面的代码:
$('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 } });
它完美地为我工作。
我发现了Grsmto的解决scheme的一个变种, 丹尼斯的解决scheme解决了我的问题。
$(".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 } }); });
我发现使用mousedown事件而不是click事件更有用。 如果用户使用点击事件点击页面上的其他元素,则点击事件不起作用。 结合jQuery的one()方法,它看起来像这样:
$("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(); });
$("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 } };
最好只在菜单可见的情况下设置监听器,并且在隐藏菜单后始终删除监听器。
即使我遇到了同样的情况,我的一位导师把这个想法交给了我自己。
第一步:点击我们应该显示下拉菜单的button。 然后将下面的类名称“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是要隐藏下拉菜单的函数
第三步,隐藏下拉菜单的重要一步就是删除之前添加的那个类
$('#more-wrap-bg').remove();
我通过在上面的代码中使用它的ID删除
.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; }
我想你需要这样的东西: 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(); } }); }); });
我希望它对你有用!
使用':可见'select器。 哪里.menuitem是隐藏元素(S)…
$('body').click(function(){ $('.menuitem:visible').hide('fast'); });
或者,如果你已经有一个var的.menuitem元素(s)…
var menitems = $('.menuitem'); $('body').click(function(){ menuitems.filter(':visible').hide('fast'); });