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

Geo*_*rge 106 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> 
Run Code Online (Sandbox Code Playgroud)

我尝试过这样的$('document[id!=MainOptSubMenu]').click(function()事情,认为它会触发菜单上的任何东西,但它没有用.

Jon*_*n W 194

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

如何检测元素外部的单击?

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

$('#menucontainer').click(function(event){
    event.stopPropagation();
});
Run Code Online (Sandbox Code Playgroud)

  • 它非常美丽,但你应该使用$('html').click()不是正文.身体总是有其内容的高度.它没有很多内容或屏幕非常高,它只适用于身体填充的部分.复制自:http://stackoverflow.com/questions/152975/how-to-detect-a-click-outside-an-element - meo 2011年2月25日15:35 (15认同)
  • 这种方法的唯一问题是已经有点击监听器的对象由于其他原因而停止传播没有任何效果.我明白为什么会这样,但它仍然是这个解决方案的限制. (3认同)

adr*_*nat 52

答案是正确的,但它会添加一个监听器,每次在页面上发生单击时都会触发该监听器.为避免这种情况,您只需添加一次侦听器:

$('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);
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

编辑:如果你想避开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');
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案,但我不得不在Chrome中使用`e.stopPropagation()`来阻止第一个事件在`one()`处理程序中触发 (2认同)

Kem*_*min 17

如果使用插件在你的情况下确定,那么我建议位于本Alman的clickoutside插件在这里:

它的用法很简单:

$('#menu').bind('clickoutside', function (event) {
    $(this).hide();
});
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.


Cod*_*der 15

stopPropagation选项是不好的,因为他们可以与其他的事件处理程序,包括可能已经接近连接处理的HTML元素其他菜单干扰.

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

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


DA.*_*DA. 8

您可以调查的2个选项:

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


小智 5

那这个呢?

    $(this).mouseleave(function(){  
        var thisUI = $(this);
        $('html').click(function(){
                thisUI.hide();
            $('html').unbind('click');
         });
     });
Run Code Online (Sandbox Code Playgroud)


小智 5

我找到了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
        }
    });
});
Run Code Online (Sandbox Code Playgroud)


小智 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();
    }
});
Run Code Online (Sandbox Code Playgroud)

stopPropagation()是个坏主意,它破坏了许多事物的标准行为,包括按钮和链接。


小智 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
     }
    });
Run Code Online (Sandbox Code Playgroud)

它对我来说非常有用.