如何检测元素外的点击?
我有一些HTML菜单,当用户点击这些菜单的头部时,我会完全显示这些菜单。 当用户点击菜单区域外时,我想隐藏这些元素。
是这样的jQuery可能吗?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
注意:使用stopEventPropagation()
是应该避免的,因为它会打破DOM中的正常事件流。 有关更多信息,请参阅此文章。 考虑使用这种方法。
将单击事件附加到关闭窗口的文档主体。 将一个单独的点击事件附加到停止传播到文档主体的窗口。
$(window).click(function() {
//Hide the menus if visible
});
$('#menucontainer').click(function(event){
event.stopPropagation();
});
您可以侦听document
上的单击事件,然后使用.closest()
确保#menucontainer
不是单击元素的祖先或目标。
如果不是,则单击的元素位于#menucontainer
之外,您可以安全地隐藏它。
$(document).click(function(event) {
if(!$(event.target).closest('#menucontainer').length) {
if($('#menucontainer').is(":visible")) {
$('#menucontainer').hide();
}
}
});
编辑 - 2017-06-23
如果您打算关闭菜单并希望停止监听事件,则还可以在事件监听器之后进行清理。 此函数将只清理新创建的侦听器,保留document
上的其他任何点击侦听器。 使用ES2015语法:
export function hideOnClickOutside(selector) {
const outsideClickListener = (event) => {
if (!$(event.target).closest(selector).length) {
if ($(selector).is(':visible')) {
$(selector).hide()
removeClickListener()
}
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
编辑 - 2018-03-11
对于那些不想使用jQuery的人。 这里是普通vanillaJS(ECMAScript6)中的上述代码。
function hideOnClickOutside(element) {
const outsideClickListener = event => {
if (!element.contains(event.target)) { // or use: event.target.closest(selector) === null
if (isVisible(element)) {
element.style.display = 'none'
removeClickListener()
}
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ) // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
注意:这是基于Alex的评论,只是使用!element.contains(event.target)
而不是jQuery部分。
但是element.closest()
现在在所有主流浏览器中都可用(W3C版本与jQuery版本有点不同)。 Polyfills可以在这里找到:https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
如何检测元素外的点击?
这个问题如此受欢迎并有如此多答案的原因是它看起来很复杂。 经过近八年的时间和几十个答案,我真的很惊讶地发现,对可访问性的关注很少。
当用户点击菜单区域外时,我想隐藏这些元素。
这是一个崇高的事业,是实际的问题。 问题的题目 - 这是大多数答案似乎试图解决的问题 - 包含一个不幸的红色鲱鱼。
提示:这是“点击”一词!
你实际上不想绑定点击处理程序。
如果你绑定了点击处理程序来关闭对话框,那么你已经失败了。 你失败的原因是不是每个人都触发click
事件。 不使用鼠标的用户将能够通过按下Tab键来跳出对话框(并且弹出菜单可以说是一种对话框类型),然后他们将无法读取对话框后面的内容,而不会随后触发click
事件。
所以我们来重述一下这个问题。
当用户完成对话时,如何关闭对话框?
这是目标。 不幸的是,现在我们需要绑定用户完成的userisfinishedwiththedialog
事件,并且绑定并不那么直截了当。
那么我们如何检测到用户已经完成了使用对话?
focusout
活动
一个好的开始是确定焦点是否已经离开对话。
提示:注意blur
事件,如果事件被绑定到冒泡阶段, blur
不会传播!
jQuery的focusout
将会很好。 如果你不能使用jQuery,那么你可以在捕获阶段使用blur
:
element.addEventListener('blur', ..., true);
// use capture: ^^^^
另外,对于许多对话框,您需要允许容器获得焦点。 添加tabindex="-1"
以允许对话框动态接收焦点,而不会中断Tab键流。
$('a').on('click', function () {
$(this.hash).toggleClass('active').focus();
});
$('div').on('focusout', function () {
$(this).removeClass('active');
});
div {
display: none;
}
.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>
链接地址: http://www.djcxy.com/p/271.html