我正在制作一个弹出菜单。用户单击它来显示菜单,然后如果他们单击弹出菜单之外的区域,我想隐藏它。
我可以找到很多解决方案(最流行的是: How do I detect a click outside an element? ),但它们似乎都有相同的问题。
它们依赖于处理冒泡到窗口元素的点击。
他们的逻辑:
所有点击都会冒泡到窗口元素。处理这些点击 - 如果菜单打开,则将其关闭。还可以调用 preventDefault
来停止跟踪任何链接(假设用户在单击菜单外部时碰巧单击了某个链接 - 我们不想跟踪该链接)
$(window).click(function(e) {
if (!e.isDefaultPrevented()) {
if($('.mainNav').hasClass('menuVisible')){
//stop any other actions happening (e.g. following a link)
e.preventDefault();
//Hide the menus
$('.mainNav').removeClass('menuVisible');
}
}
});
问题
如果用户点击的内容本身恰好有一个 onclick
事件,那么该代码仍然会被触发。树下方的元素甚至首先获得点击,因此我无法使用 preventDefault
或 stopPropagation
来停止这些事件..
有什么解决办法吗?我唯一的想法是在整个屏幕的所有内容之上放置一个透明的 div 以首先捕获点击?
最佳答案
您需要使用 addEventListener()
和 useCapture
属性。 useCapture 属性允许首先触发 DOM 树中较高层对象的事件。然后,您可以防止发生正常的点击行为:
var button = document.getElementById("myButton");
var response = document.getElementById("myResponse");
var windowClick = function (evt) {
response.innerHTML += "<p>The Window</p>";
evt.stopPropagation ();
}
var buttonClick = function (evt) {
response.innerHTML += "<p>The Button</p>";
evt.stopPropagation ();
}
button.addEventListener("click", buttonClick);
// If true, the window event fires first, if false, the button fires first.
var useCapture = true;
window.addEventListener("click", windowClick, useCapture);
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<button id="myButton">Hello!</button>
<div id="myResponse">Who Clicked?</div>
</body>
</html>
关于javascript - JQuery 检测元素外部的点击并停止所有其他点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45736739/