So I have a drop-down menu that shows on a click, as per business requirements. The menu becomes hidden again after you mouse away from it.
因此,我有一个下拉菜单,按业务需求在单击时显示。鼠标离开菜单后,菜单再次隐藏。
But now I am being asked to have it stay in place until user clicks anywhere on the document. How can this be accomplished?
但是现在我被要求在用户点击文档上的任何地方之前保持它的位置。这是如何实现的呢?
This is a simplified version of what I have now:
这是我现在的简化版:
$(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>
I tried something like this $('document[id!=MainOptSubMenu]').click(function()
thinking it would trigger on anything that wasnt the menu, but it didnt work.
我尝试了类似$('document[id!=MainOptSubMenu]).click(function(),以为它会触发菜单之外的任何东西,但它不起作用。
14 个解决方案
#1
184
Take a look at the approach this question used:
看看这个问题所使用的方法:
How do I detect a click outside an element?
如何检测元素外的单击?
Attach a click event to the document body which closes the window. Attach a separate click event to the window which stops propagation to the document body.
$('html').click(function() {
//Hide the menus if visible
});
$('#menucontainer').click(function(event){
event.stopPropagation();
});
#2
48
The answer is right, but it will add a listener that will be triggered every time a click occurs on your page. To avoid that, you can add the listener for just one time :
答案是正确的,但是它会添加一个监听器,每次点击出现在页面上时,都会触发一个监听器。为了避免这种情况,您可以只添加侦听器一次:
$('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);
}
});
});
Edit: if you want to avoid the stopPropagation()
on the initial button you can use this
编辑:如果您想避免初始按钮上的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');
}
});
#3
16
If using a plugin is ok in you case, then I suggest Ben Alman's clickoutside plugin located here:
如果你用的是插件,那么我建议本·阿尔曼的clickoutside插件在这里:
its usage is as simple as this:
它的用法很简单:
$('#menu').bind('clickoutside', function (event) {
$(this).hide();
});
hope this helps.
希望这个有帮助。
#4
13
The stopPropagation options are bad because they can interfere with other event handlers including other menus that might have attached close handlers to the html element.
停止传播选项是不好的,因为它们会干扰其他的事件处理程序,包括其他可能对html元素附加了紧密处理程序的菜单。
Here is a simple solution based on user2989143's answer:
下面是一个基于user2989143的简单解决方案:
$("html").click(function(event) {
if ($(event.target).closest('#menu-container, #menu-activator').length === 0) {
$('#menu-container').hide();
}
});
#5
7
2 options that you can investigate:
你可以调查的两个选项:
- On showing of the menu, place a large empty DIV behind it covering up the rest of the page and give that an on-click event to close the menu (and itself). This is akin to the methods used with lightboxes where clicking on the background closes the lightbox
- 在显示菜单时,在菜单后面放置一个大的空DIV,覆盖页面的其余部分,并给它一个单击事件来关闭菜单(以及它自己)。这类似于lightbox使用的方法,即单击背景会关闭lightbox
- On showing of the menu, attach a one-time click event handler on the body that closes the menu. You use jQuery's '.one()' for this.
- 在显示菜单时,在关闭菜单的主体上附加一次性单击事件处理程序。为此使用jQuery的'.one()'。
#6
4
what about this?
这是什么?
$(this).mouseleave(function(){
var thisUI = $(this);
$('html').click(function(){
thisUI.hide();
$('html').unbind('click');
});
});
#7
4
I found a variant of Grsmto's solution and Dennis' solution fixed my issue.
我发现了Grsmto的解决方案的变体,Dennis的解决方案解决了我的问题。
$(".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
}
});
});
#8
4
I use this solution with multiple elements with the same behavior in the same page:
我使用这个解决方案的多个元素具有相同的行为在同一页:
$("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() is a bad idea, this breaks standard behaviour of many things, including buttons and links.
stopPropagation()是一个坏主意,它破坏了许多东西的标准行为,包括按钮和链接。
#9
4
I have recently faced the same issue. I wrote the following code:
我最近也遇到了同样的问题。我写了以下代码:
$('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
}
});
It has worked for me perfectly.
这对我来说非常有效。
#10
3
I find it more useful to use mousedown-event instead of click-event. The click-event doesn't work if the user clicks on other elements on the page with click-events. In combination with jQuery's one() method it looks like this:
我发现使用鼠标向下事件而不是单击事件更有用。如果用户使用单击事件单击页面上的其他元素,则单击事件将不起作用。结合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();
});
#11
3
even i came across the same situation and one of my mentor put this idea across to myself.
甚至我遇到了同样的情况,我的一位导师把这个想法告诉了我自己。
step:1 when clicked on the button on which we should show the drop down menu. then add the below class name "more_wrap_background" to the current active page like shown below
步骤:1当点击按钮时,我们应该显示下拉菜单。然后将下面的类名“more_wrap_background”添加到当前活动页面,如下所示。
$('.ui-page-active').append("<div class='more_wrap_background' id='more-wrap-bg'> </div>");
step-2 then add a clicks for the div tag like
step2然后添加div标签的点击。
$(document).on('click', '#more-wrap-bg', hideDropDown);
where hideDropDown is the function to be called to hide drop down menu
要调用隐藏下拉菜单的隐藏下拉菜单在哪里
Step-3 and important step while hiding the drop down menu is that remove that class you that added earlier like
步骤3隐藏下拉菜单的重要步骤是删除前面添加的类
$('#more-wrap-bg').remove();
I am removing by using its id in the above code
我正在使用上面代码中的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;
}
#12
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
}
};
And better to set the listener only when your menu is being visible and always remove the listener after menu becomes hidden.
最好只在菜单可见时设置监听器,并在菜单隐藏后删除监听器。
#13
1
I think you need something like this: http://jsfiddle.net/BeenYoung/BXaqW/3/
我想你需要这样的东西: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();
}
});
});
});
I hope it useful for you!
我希望它对你有用!
#14
1
Use the ':visible' selector. Where .menuitem is the to-hide element(s) ...
使用选择器:可见。其中.menuitem是to-hide元素…
$('body').click(function(){
$('.menuitem:visible').hide('fast');
});
Or if you already have the .menuitem element(s) in a var ...
或者,如果您已经在一个var中拥有.menuitem元素(s)…
var menitems = $('.menuitem');
$('body').click(function(){
menuitems.filter(':visible').hide('fast');
});
#1
184
Take a look at the approach this question used:
看看这个问题所使用的方法:
How do I detect a click outside an element?
如何检测元素外的单击?
Attach a click event to the document body which closes the window. Attach a separate click event to the window which stops propagation to the document body.
$('html').click(function() {
//Hide the menus if visible
});
$('#menucontainer').click(function(event){
event.stopPropagation();
});
#2
48
The answer is right, but it will add a listener that will be triggered every time a click occurs on your page. To avoid that, you can add the listener for just one time :
答案是正确的,但是它会添加一个监听器,每次点击出现在页面上时,都会触发一个监听器。为了避免这种情况,您可以只添加侦听器一次:
$('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);
}
});
});
Edit: if you want to avoid the stopPropagation()
on the initial button you can use this
编辑:如果您想避免初始按钮上的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');
}
});
#3
16
If using a plugin is ok in you case, then I suggest Ben Alman's clickoutside plugin located here:
如果你用的是插件,那么我建议本·阿尔曼的clickoutside插件在这里:
its usage is as simple as this:
它的用法很简单:
$('#menu').bind('clickoutside', function (event) {
$(this).hide();
});
hope this helps.
希望这个有帮助。
#4
13
The stopPropagation options are bad because they can interfere with other event handlers including other menus that might have attached close handlers to the html element.
停止传播选项是不好的,因为它们会干扰其他的事件处理程序,包括其他可能对html元素附加了紧密处理程序的菜单。
Here is a simple solution based on user2989143's answer:
下面是一个基于user2989143的简单解决方案:
$("html").click(function(event) {
if ($(event.target).closest('#menu-container, #menu-activator').length === 0) {
$('#menu-container').hide();
}
});
#5
7
2 options that you can investigate:
你可以调查的两个选项:
- On showing of the menu, place a large empty DIV behind it covering up the rest of the page and give that an on-click event to close the menu (and itself). This is akin to the methods used with lightboxes where clicking on the background closes the lightbox
- 在显示菜单时,在菜单后面放置一个大的空DIV,覆盖页面的其余部分,并给它一个单击事件来关闭菜单(以及它自己)。这类似于lightbox使用的方法,即单击背景会关闭lightbox
- On showing of the menu, attach a one-time click event handler on the body that closes the menu. You use jQuery's '.one()' for this.
- 在显示菜单时,在关闭菜单的主体上附加一次性单击事件处理程序。为此使用jQuery的'.one()'。
#6
4
what about this?
这是什么?
$(this).mouseleave(function(){
var thisUI = $(this);
$('html').click(function(){
thisUI.hide();
$('html').unbind('click');
});
});
#7
4
I found a variant of Grsmto's solution and Dennis' solution fixed my issue.
我发现了Grsmto的解决方案的变体,Dennis的解决方案解决了我的问题。
$(".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
}
});
});
#8
4
I use this solution with multiple elements with the same behavior in the same page:
我使用这个解决方案的多个元素具有相同的行为在同一页:
$("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() is a bad idea, this breaks standard behaviour of many things, including buttons and links.
stopPropagation()是一个坏主意,它破坏了许多东西的标准行为,包括按钮和链接。
#9
4
I have recently faced the same issue. I wrote the following code:
我最近也遇到了同样的问题。我写了以下代码:
$('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
}
});
It has worked for me perfectly.
这对我来说非常有效。
#10
3
I find it more useful to use mousedown-event instead of click-event. The click-event doesn't work if the user clicks on other elements on the page with click-events. In combination with jQuery's one() method it looks like this:
我发现使用鼠标向下事件而不是单击事件更有用。如果用户使用单击事件单击页面上的其他元素,则单击事件将不起作用。结合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();
});
#11
3
even i came across the same situation and one of my mentor put this idea across to myself.
甚至我遇到了同样的情况,我的一位导师把这个想法告诉了我自己。
step:1 when clicked on the button on which we should show the drop down menu. then add the below class name "more_wrap_background" to the current active page like shown below
步骤:1当点击按钮时,我们应该显示下拉菜单。然后将下面的类名“more_wrap_background”添加到当前活动页面,如下所示。
$('.ui-page-active').append("<div class='more_wrap_background' id='more-wrap-bg'> </div>");
step-2 then add a clicks for the div tag like
step2然后添加div标签的点击。
$(document).on('click', '#more-wrap-bg', hideDropDown);
where hideDropDown is the function to be called to hide drop down menu
要调用隐藏下拉菜单的隐藏下拉菜单在哪里
Step-3 and important step while hiding the drop down menu is that remove that class you that added earlier like
步骤3隐藏下拉菜单的重要步骤是删除前面添加的类
$('#more-wrap-bg').remove();
I am removing by using its id in the above code
我正在使用上面代码中的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;
}
#12
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
}
};
And better to set the listener only when your menu is being visible and always remove the listener after menu becomes hidden.
最好只在菜单可见时设置监听器,并在菜单隐藏后删除监听器。
#13
1
I think you need something like this: http://jsfiddle.net/BeenYoung/BXaqW/3/
我想你需要这样的东西: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();
}
});
});
});
I hope it useful for you!
我希望它对你有用!
#14
1
Use the ':visible' selector. Where .menuitem is the to-hide element(s) ...
使用选择器:可见。其中.menuitem是to-hide元素…
$('body').click(function(){
$('.menuitem:visible').hide('fast');
});
Or if you already have the .menuitem element(s) in a var ...
或者,如果您已经在一个var中拥有.menuitem元素(s)…
var menitems = $('.menuitem');
$('body').click(function(){
menuitems.filter(':visible').hide('fast');
});