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

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

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

当前回答

这里还有一个解决方案:

http://jsfiddle.net/zR76D/

用法:

<div onClick="$('#menu').toggle();$('#menu').clickOutside(function() { $(this).hide(); $(this).clickOutside('disable'); });">Open / Close Menu</div>
<div id="menu" style="display: none; border: 1px solid #000000; background: #660000;">I am a menu, whoa is me.</div>

插件:

(function($) {
    var clickOutsideElements = [];
    var clickListener = false;

    $.fn.clickOutside = function(options, ignoreFirstClick) {
        var that = this;
        if (ignoreFirstClick == null) ignoreFirstClick = true;

        if (options != "disable") {
            for (var i in clickOutsideElements) {
                if (clickOutsideElements[i].element[0] == $(this)[0]) return this;
            }

            clickOutsideElements.push({ element : this, clickDetected : ignoreFirstClick, fnc : (typeof(options) != "function") ? function() {} : options });

            $(this).on("click.clickOutside", function(event) {
                for (var i in clickOutsideElements) {
                    if (clickOutsideElements[i].element[0] == $(this)[0]) {
                        clickOutsideElements[i].clickDetected = true;
                    }
                }
            });

            if (!clickListener) {
                if (options != null && typeof(options) == "function") {
                    $('html').click(function() {
                        for (var i in clickOutsideElements) {
                            if (!clickOutsideElements[i].clickDetected) {
                                clickOutsideElements[i].fnc.call(that);
                            }
                            if (clickOutsideElements[i] != null) clickOutsideElements[i].clickDetected = false;
                        }
                    });
                    clickListener = true;
                }
            }
        }
        else {
            $(this).off("click.clickoutside");
            for (var i = 0; i < clickOutsideElements.length; ++i) {
                if (clickOutsideElements[i].element[0] == $(this)[0]) {
                    clickOutsideElements.splice(i, 1);
                }
            }
        }

        return this;
    }
})(jQuery);

其他回答

该事件具有元素的名为event.path的属性,该属性是“以树顺序列出其所有祖先的静态有序列表”。要检查事件是否源自特定DOM元素或其子元素之一,只需检查该特定DOM元素的路径。它还可以用于通过在some函数中对元素检查进行逻辑“或”运算来检查多个元素。

$(“body”).click(函数){target=document.getElementById(“main”);flag=event.path.some(函数(el,i,arr){返回(el==目标)})if(标志){console.log(“内部”)}其他{console.log(“外部”)}});#主要的,主要的{显示:内联块;背景:黄色;}<script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script><div id=“main”><ul><li>测试总管</li><li>测试总管</li><li>测试总管</li><li>测试总管</li><li>测试总管</li></ul></div><div id=“main2”>外部主管道</div>

所以你的情况应该是

$("body").click(function() {
  target = $("#menuscontainer")[0];
  flag = event.path.some(function(el, i, arr) {
    return (el == target)
  });
  if (!flag) {
    // Hide the menus
  }
});

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

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);

这是面向未来观众的普通JavaScript解决方案。

单击文档中的任何元素时,如果已切换所单击元素的id,或者隐藏元素未隐藏且隐藏元素不包含所单击元素,则切换该元素。

(function () {
    "use strict";
    var hidden = document.getElementById('hidden');
    document.addEventListener('click', function (e) {
        if (e.target.id == 'toggle' || (hidden.style.display != 'none' && !hidden.contains(e.target))) hidden.style.display = hidden.style.display == 'none' ? 'block' : 'none';
    }, false);
})();

(函数(){“使用严格”;var hidden=document.getElementById('hidden');document.addEventListener('click',函数(e){如果(e.target.id==“toggle”| |(hidden.style.display!=“none”&&!hidden.concloss(e.target)))hidden.syle.display=hidden.sstyle.display==“none?”block':'无';},假);})();<a href=“javascript:void(0)”id=“toggle”>切换隐藏潜水</a><div id=“hidden”style=“display:none;”>此内容通常是隐藏的。单击此内容以外的任何位置,使我消失</div>

如果您要在同一页面上进行多个切换,可以使用以下方式:

将隐藏的类名添加到可折叠项中。单击文档后,关闭所有不包含所单击元素且未隐藏的隐藏元素如果单击的元素是切换,请切换指定的元素。

(函数(){“使用严格”;var hiddenItems=document.getElementsByClassName('hidden'),隐藏;document.addEventListener('click',函数(e){for(var i=0;hidden=hiddenItems[i];i++){如果(!hidden.contains(e.target)&&hidden.style.display!='无”)hidden.style.display=“无”;}if(e.target.getAttribute('data-toggle')){var toggle=document.querySelector(e.target.getAttribute('data-toggle'));toggle.style.display=toggle.style.display==“无”?'block':'无';}},假);})();<a href=“javascript:void(0)”data toggle=“#hidden1”>切换隐藏潜水</a><div class=“hidden”id=“hidden1”style=“display:none;”data hidden=“true”>此内容通常隐藏</div><a href=“javascript:void(0)”data toggle=“#hidden2”>切换隐藏潜水</a><div class=“hidden”id=“hidden2”style=“display:none;”data hidden=“true”>此内容通常隐藏</div><a href=“javascript:void(0)”data toggle=“#hidden3”>切换隐藏潜水</a><div class=“hidden”id=“hidden3”style=“display:none;”data hidden=“true”>此内容通常隐藏</div>

我们实现了一个解决方案,部分基于上面用户的评论,这非常适合我们。我们使用它来隐藏搜索框/结果,当在这些元素之外单击时,不包括最初的元素。

// HIDE SEARCH BOX IF CLICKING OUTSIDE
$(document).click(function(event){ 
    // IF NOT CLICKING THE SEARCH BOX OR ITS CONTENTS OR SEARCH ICON 
    if ($("#search-holder").is(":visible") && !$(event.target).is("#search-holder *, #search")) {
        $("#search-holder").fadeOut('fast');
        $("#search").removeClass('active');
    }
});

它首先检查搜索框是否已经可见,在我们的例子中,它还删除了隐藏/显示搜索按钮上的活动类。

Use:

var go = false;
$(document).click(function(){
    if(go){
        $('#divID').hide();
        go = false;
    }
})

$("#divID").mouseover(function(){
    go = false;
});

$("#divID").mouseout(function (){
    go = true;
});

$("btnID").click( function(){
    if($("#divID:visible").length==1)
        $("#divID").hide(); // Toggle
    $("#divID").show();
});