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

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

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

当前回答

使用可访问性焦点

这里有一个答案说(非常正确),关注点击事件是一个可访问性问题,因为我们想迎合键盘用户。在这里使用focusout事件是正确的,但它可以比其他答案(以及纯JavaScript)简单得多:

更简单的方法是:

使用focusout的“问题”是,如果对话框/模式/菜单中的某个元素由于“内部”的原因而失去焦点,则事件仍然会被激发。我们可以通过查看event.relatedTarget(它告诉我们哪个元素将获得焦点)来检查情况是否并非如此。

dialog = document.getElementById("dialogElement")

dialog.addEventListener("focusout", function (event) {
    if (
        // We are still inside the dialog so don't close
        dialog.contains(event.relatedTarget) ||
        // We have switched to another tab so probably don't want to close
        !document.hasFocus()
    ) {
        return;
    }
    dialog.close();  // Or whatever logic you want to use to close
});

上面有一个小错误,那就是relatedTarget可能为空。如果用户在对话框外单击,这很好,但如果用户在对话内单击,而对话框恰好不可聚焦,则会出现问题。要解决此问题,必须确保将tabIndex设置为0,以便对话框可聚焦。

其他回答

投票选出最受欢迎的答案,但添加

&& (e.target != $('html').get(0)) // ignore the scrollbar

因此,单击滚动条不会隐藏目标元素。

这是我对这个问题找到的最简单的答案:

window.addEventListener('click', close_window = function () {
  if(event.target !== windowEl){
    windowEl.style.display = "none";
    window.removeEventListener('click', close_window, false);
  }
});

您将看到我将函数命名为“close_window”,以便在窗口关闭时删除事件侦听器。

功能:

$(function() {
    $.fn.click_inout = function(clickin_handler, clickout_handler) {
        var item = this;
        var is_me = false;
        item.click(function(event) {
            clickin_handler(event);
            is_me = true;
        });
        $(document).click(function(event) {
            if (is_me) {
                is_me = false;
            } else {
                clickout_handler(event);
            }
        });
        return this;
    }
});

用法:

this.input = $('<input>')
    .click_inout(
        function(event) { me.ShowTree(event); },
        function() { me.Hide(); }
    )
    .appendTo(this.node);

功能非常简单:

ShowTree: function(event) {
    this.data_span.show();
}
Hide: function() {
    this.data_span.hide();
}

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

使用流中断、模糊/聚焦事件或任何其他棘手的技术,只需将事件流与元素的亲属关系匹配即可:

$(document).on("click.menu-outside", function(event){
    // Test if target and it's parent aren't #menuscontainer
    // That means the click event occur on other branch of document tree
    if(!$(event.target).parents().andSelf().is("#menuscontainer")){
        // Click outisde #menuscontainer
        // Hide the menus (but test if menus aren't already hidden)
    }
});

要删除事件侦听器外部的单击,只需执行以下操作:

$(document).off("click.menu-outside");