单击外部菜单以在jquery中关闭

时间:2010-05-19 19:08:57

标签: 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()这样的东西,认为它会触发菜单上的任何东西,但它没有用。

16 个答案:

答案 0 :(得分:191)

看看这个问题使用的方法:

How do I detect a click outside an element?

将单击事件附加到关闭窗口的文档正文。将单独的单击事件附加到窗口,该窗口将停止传播到文档正文。
$('html').click(function() {
  //Hide the menus if visible
});

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

答案 1 :(得分:51)

答案是对的,但它会添加一个每次点击页面时都会触发的监听器。为避免这种情况,您只需添加一次侦听器:

$('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');
    }
});

答案 2 :(得分:17)

如果在你的情况下使用插件是好的,那么我建议Ben Alman的clickoutside插件位于here

它的用法很简单:

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

希望这会有所帮助。

答案 3 :(得分:14)

stopPropagation选项很糟糕,因为它们可能会干扰其他事件处理程序,包括可能附加了HTML元素的处理程序的其他菜单。

这是一个基于 user2989143 的答案的简单解决方案:

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

答案 4 :(得分:8)

您可以调查的两个选项:

  • 在显示菜单时,在其后面放置一个大的空DIV,覆盖页面的其余部分并给出一个点击事件以关闭菜单(及其自身)。这类似于灯箱使用的方法,其中点击背景关闭灯箱
  • 在显示菜单时,在关闭菜单的主体上附加一次性单击事件处理程序。你使用jQuery的'.one()'。

答案 5 :(得分:5)

我发现Grsmto's solutionDennis' 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
        }
    });
});

答案 6 :(得分:5)

我在同一页面中使用具有相同行为的多个元素的此解决方案:

$("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()是一个坏主意,这打破了许多事情的标准行为,包括按钮和链接。

答案 7 :(得分:5)

我最近遇到了同样的问题。我写了以下代码:

    $('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
     }
    });

它对我有用。

答案 8 :(得分:4)

这是怎么回事?

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

答案 9 :(得分:3)

即使我遇到了同样的情况,我的一位导师也把这个想法告诉了自己。

步骤:1 当点击我们应该显示下拉菜单的按钮时。然后将以下类名“more_wrap_background”添加到当前活动页面,如下所示

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

step-2 然后为div标签添加点击次数,例如

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

其中hideDropDown是要调用以隐藏下拉菜单的函数

隐藏下拉菜单时,

步骤3 和重要步骤是删除之前添加的类

$('#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;
}

答案 10 :(得分:3)

我发现使用mousedown-event而不是click-event更有用。如果用户使用点击事件点击页面上的其他元素,则点击事件不起作用。结合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 :(得分: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
    }
};

最好只在菜单可见时设置监听器,并在菜单隐藏后始终删除监听器。

答案 12 :(得分: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();               
            }
      });
  });    
});

我希望它对你有用!

答案 13 :(得分:1)

使用&#39;:可见&#39;选择。 其中.menuitem是隐藏元素......

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

或者如果你已经在var ...

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

答案 14 :(得分:0)

不必太复杂。

$(document).on('click', function() {
    $("#menu:not(:hover)").hide();
});

答案 15 :(得分:0)

如果您不使用 jQuery 并且想使用纯 CSS 和 HTML 来实现,这就是解决方案。

  • 创建一个触发器元素并在其中写入您的弹出元素。
  • 附加点击处理程序以取消隐藏触发元素点击时的弹出窗口。
  • 有一个可以延伸到整个屏幕宽度的背景元素,并将点击处理程序附加到隐藏弹出窗口的元素上。
  • 所有附加的点击处理程序都应停止传播事件,以免调用其他处理程序。

在下面找到实时代码

function showPopup(bShow,args){
  var popupContainer = document.getElementsByClassName('popup-container')[0];
  debugger;
  if(!bShow){
    popupContainer.classList.add('hide-element')
  }else{
    popupContainer.classList.remove('hide-element')
  }
  args[0].stopPropagation();
}
.popup-trigger{
  cursor: pointer;
  margin: 10px;
  padding: 5px;
  width: fit-content;
  background: red;
  border-radius: 5px;
  position: relative;
}

.body{
  width: 100%;
  height: 1000px;
  background: yellow;
  padding: 10px;
}

.backdrop{
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

.actual-popup{
}
.popup-container{
 top: 30px;
 width: 100px;
 height: 50px;
 background: grey;
 display: flex;
 justify-content: center;
 align-items: center;
 position: absolute;
}

.hide-element{
  visibility: hidden;
}
<div class="body">

  <div onclick="showPopup(true,arguments)" class="popup-trigger">Click to open dialog with button
    <div onclick="showPopup(false,arguments)" class='popup-container hide-element'> 
     <div onclick="showPopup(false,arguments)" class='backdrop'>  </div>
     <div onclick="showPopup(true,arguments)" class='actual-popup'> 
        <button onclick="showPopup(false,arguments)"> close me </button>
     </div>
     
    </div>
   
  </div>
</div>