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

JavaScript

猴子村村

2020-03-09

我有一些HTML菜单,当用户单击这些菜单的标题时,它们会完整显示。当用户在菜单区域之外单击时,我想隐藏这些元素。

jQuery可能会发生这种情况吗?

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

第183篇《如何检测元素外部的点击?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

9个回答
飞云LEY 2020.03.09

将单击事件侦听器挂在文档上。在事件侦听器内部,您可以查看事件对象,特别是event.target,以查看单击了哪个元素:

$(document).click(function(e){
    if ($(e.target).closest("#menuscontainer").length == 0) {
        // .closest can help you determine if the element 
        // or one of its ancestors is #menuscontainer
        console.log("hide");
    }
});
十三小卤蛋凯 2020.03.09
$(document).click(function() {
    $(".overlay-window").hide();
});
$(".overlay-window").click(function() {
    return false;
});

如果单击文档,则隐藏给定元素,除非您单击相同的元素。

Gil番长 2020.03.09

如果您正在为IE和FF 3. *编写脚本,并且只想知道单击是否发生在某个框区域内,则还可以使用类似以下内容的方法:

this.outsideElementClick = function(objEvent, objElement){   
var objCurrentElement = objEvent.target || objEvent.srcElement;
var blnInsideX = false;
var blnInsideY = false;

if (objCurrentElement.getBoundingClientRect().left >= objElement.getBoundingClientRect().left && objCurrentElement.getBoundingClientRect().right <= objElement.getBoundingClientRect().right)
    blnInsideX = true;

if (objCurrentElement.getBoundingClientRect().top >= objElement.getBoundingClientRect().top && objCurrentElement.getBoundingClientRect().bottom <= objElement.getBoundingClientRect().bottom)
    blnInsideY = true;

if (blnInsideX && blnInsideY)
    return false;
else
    return true;}
Eva猴子古一 2020.03.09

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

$("body").click(function() {
  target = document.getElementById("main");
  flag = event.path.some(function(el, i, arr) {
    return (el == target)
  })
  if (flag) {
    console.log("Inside")
  } else {
    console.log("Outside")
  }
});
#main {
  display: inline-block;
  background:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
  <ul>
    <li>Test-Main</li>
    <li>Test-Main</li>
    <li>Test-Main</li>
    <li>Test-Main</li>
    <li>Test-Main</li>
  </ul>
</div>
<div id="main2">
  Outside Main
</div>

所以对于你的情况应该是

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

检查窗口单击事件目标(只要没有在其他任何地方捕获,它应该传播到窗口),并确保它不是任何菜单元素。如果不是,那么您就在菜单之外。

或检查单击的位置,然后查看它是否包含在菜单区域中。

阿飞Harry小胖 2020.03.09

一个简单的解决方案是:

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

上面的脚本将隐藏click事件div外部div是否被触发。

您可以查看以下博客以获取更多信息:http : //www.codecanal.com/detect-click-outside-div-using-javascript/

乐卡卡西 2020.03.09

我不认为您真正需要的是在用户单击外部时关闭菜单。您需要的是,当用户单击页面上的任意位置时,菜单关闭。如果单击菜单,或者关闭菜单,它应该关闭吗?

上面找不到满意的答案,促使我前几天写了这篇博客对于更加学究的人来说,有许多陷阱需要注意:

  1. 如果在单击时将click事件处理程序附加到body元素,请确保在关闭菜单并取消绑定事件之前等待第二次单击。否则,打开菜单的click事件将冒泡到必须关闭菜单的侦听器中。
  2. 如果在click事件上使用event.stopPropogation(),则页面中的其他任何元素都不能具有“单击任何位置关闭”功能。
  3. 将click事件处理程序无限期地附加到body元素上并不是一种有效的解决方案
  4. 比较事件的目标以及事件的父对象与处理程序的创建者的比较,您假设您想要的是在单击菜单时关闭菜单,而您真正想要的是在单击页面上的任意位置时关闭菜单。
  5. 在body元素上侦听事件将使您的代码更加脆弱。像这样天真无邪的样式会破坏它:body { margin-left:auto; margin-right: auto; width:960px;}
西门Harry 2020.03.09

现在有一个用于此的插件:外部事件博客文章

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

  • 将该元素添加到一个数组,该数组包含带有clickoutside处理程序的所有元素
  • 命名空间的单击处理程序已绑定到文档(如果尚未存在)
  • 文档中的任何单击上,都会为该数组中与click -events目标不相等或为父的那些元素触发clickoutside事件
  • 此外,clickoutside事件的event.target 设置为用户单击的元素(因此,您甚至知道用户单击了什么,而不仅仅是他在外部单击了)

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

Pro逆天猿 2020.03.09
$("#menuscontainer").click(function() {
    $(this).focus();
});
$("#menuscontainer").blur(function(){
    $(this).hide();
});

对我有用。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android