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

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

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

当前回答

这种情况的简单解决方案是:

$(document).mouseup(function (e)
{
    var container = $("YOUR SELECTOR"); // Give you class or ID
    
    if (!container.is(e.target) &&            // If the target of the click is not the desired div or section
        container.has(e.target).length === 0) // ... nor a descendant-child of the container
    {
        container.hide();
    }
});

如果在div单击事件之外触发,上述脚本将隐藏div。

其他回答

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

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

这是我的代码:

// Listen to every click
$('html').click(function(event) {
    if ( $('#mypopupmenu').is(':visible') ) {
        if (event.target.id != 'click_this_to_show_mypopupmenu') {
            $('#mypopupmenu').hide();
        }
    }
});

// Listen to selector's clicks
$('#click_this_to_show_mypopupmenu').click(function() {

  // If the menu is visible, and you clicked the selector again we need to hide
  if ( $('#mypopupmenu').is(':visible') {
      $('#mypopupmenu').hide();
      return true;
  }

  // Else we need to show the popup menu
  $('#mypopupmenu').show();
});

作为Art这个伟大答案的包装,并使用OP最初要求的语法,这里有一个jQuery扩展,它可以记录在集合元素之外是否发生了单击。

$.fn.clickOutsideThisElement = function (callback) {
    return this.each(function () {
        var self = this;
        $(document).click(function (e) {
            if (!$(e.target).closest(self).length) {
                callback.call(self, e)
            }
        })
    });
};

然后你可以这样打电话:

$("#menuscontainer").clickOutsideThisElement(function() {
    // handle menu toggle
});

这是小提琴演示

还在寻找检测外部点击的完美解决方案?别再看了!介绍Clickout Event,这是一个为Clickout和其他类似事件提供通用支持的包,它适用于所有场景:普通HTML onclickout属性、普通JavaScript的.addEventListener('clickkout')、jQuery的.on('click kout'”)、Vue.js的v-on:cclickout指令。只要前端框架内部使用addEventListener来处理事件,Clickout Event适用于它。只需在页面中的任何位置添加脚本标记,它就会像魔术一样发挥作用。

HTML属性

<div onclickout="console.log('clickout detected')">...</div>

香草JavaScript

document.getElementById('myId').addEventListener('clickout', myListener);

jQuery

$('#myId').on('clickout', myListener);

Vue.js

<div v-on:clickout="open=false">...</div>

有棱角的

<div (clickout)="close()">...</div>

外部点击插件!

用法:

$('.target-element').outsideClick(function(event){
    //code that fires when user clicks outside the element
    //event = the click event
    //$(this) = the '.target-element' that is firing this function 
}, '.excluded-element')

它的代码:

(function($) {

//when the user hits the escape key, it will trigger all outsideClick functions
$(document).on("keyup", function (e) {
    if (e.which == 27) $('body').click(); //escape key
});

//The actual plugin
$.fn.outsideClick = function(callback, exclusions) {
    var subject = this;

    //test if exclusions have been set
    var hasExclusions = typeof exclusions !== 'undefined';

    //switches click event with touch event if on a touch device
    var ClickOrTouchEvent = "ontouchend" in document ? "touchend" : "click";

    $('body').on(ClickOrTouchEvent, function(event) {
        //click target does not contain subject as a parent
        var clickedOutside = !$(event.target).closest(subject).length;

        //click target was on one of the excluded elements
        var clickedExclusion = $(event.target).closest(exclusions).length;

        var testSuccessful;

        if (hasExclusions) {
            testSuccessful = clickedOutside && !clickedExclusion;
        } else {
            testSuccessful = clickedOutside;
        }

        if(testSuccessful) {
            callback.call(subject, event);
        }
    });

    return this;
};

}(jQuery));

根据此答案改编https://stackoverflow.com/a/3028037/1611058