我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。

jQuery是否可以实现这样的功能?

$("#menuscontainer").clickOutsideThisElement(function() {
    // Hide the menus
});

当前回答

jQuery().ready(function(){
    $('#nav').click(function (event) {
        $(this).addClass('activ');
        event.stopPropagation();
    });

    $('html').click(function () {
        if( $('#nav').hasClass('activ') ){
            $('#nav').removeClass('activ');
        }
    });
});

其他回答

只是一个警告,使用这个:

$('html').click(function() {
  // Hide the menus if visible
});

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

它阻止RubyonRails UJS驱动程序正常工作。例如,link_to“click”、“/url”、:method=>:delete将不起作用。

这可能是一种变通方法:

$('html').click(function() {
  // Hide the menus if visible
});

$('#menucontainer').click(function(event){
  if (!$(event.target).data('method')) {
    event.stopPropagation();
  }
});

要做到这一点,最广泛的方法是选择网页上的所有内容,除了不希望检测到点击的元素,并在打开菜单时绑定点击事件。

然后,当菜单关闭时,移除绑定。

使用.stopPropagation可防止事件影响菜单容器的任何部分。

$("*").not($("#menuscontainer")).bind("click.OutsideMenus", function ()
{
    // hide the menus

    //then remove all of the handlers
    $("*").unbind(".OutsideMenus");
});

$("#menuscontainer").bind("click.OutsideMenus", function (event) 
{
    event.stopPropagation(); 
});

现在有一个插件:外部事件(博客文章)

当clickoutside处理程序(WLOG)绑定到元素时,会发生以下情况:

元素被添加到一个数组中,该数组包含所有具有clickoutside处理程序的元素(名称空间)单击处理程序绑定到文档(如果尚未存在)在文档中的任何单击时,都会为该数组中不等于或不是单击事件目标的父级的元素触发单击外部事件此外,clickoutside事件的event.target设置为用户单击的元素(因此您甚至可以知道用户单击了什么,而不仅仅是他在外面单击了什么)

因此,不会阻止任何事件的传播,并且可以在元素的“上方”使用额外的单击处理程序和外部处理程序。

$('html').click(function(){//隐藏菜单(如果可见)});$('#menucontainer').click(函数(事件){event.stopPropagation();});<script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script><html><button id=“#menucontainer”>确定</button></html>

这里的其他解决方案不适合我,所以我不得不使用:

if(!$(event.target).is('#foo'))
{
    // hide menu
}

编辑:普通Javascript变体(2021-03-31)

我使用这个方法来处理在单击下拉菜单外部时关闭下拉菜单的问题。

首先,我为组件的所有元素创建了一个自定义类名。这个类名将被添加到组成菜单小部件的所有元素中。

const className = `dropdown-${Date.now()}-${Math.random() * 100}`;

我创建了一个函数来检查单击和单击元素的类名。如果clicked元素不包含我上面生成的自定义类名,它应该将show标志设置为false,菜单将关闭。

const onClickOutside = (e) => {
  if (!e.target.className.includes(className)) {
    show = false;
  }
};

然后,我将单击处理程序附加到窗口对象。

// add when widget loads
window.addEventListener("click", onClickOutside);

……最后还有一些家政服务

// remove listener when destroying the widget
window.removeEventListener("click", onClickOutside);