我有一些 HTML 菜单,当用户点击这些菜单的顶部时,这些菜单会完全显示出来。当用户点击菜单区域之外的区域时,我想隐藏这些元素。就像这样...
我有一些 HTML 菜单,当用户点击这些菜单的顶部时,这些菜单会完全显示出来。当用户点击菜单区域之外的区域时,我想隐藏这些元素。
使用 jQuery 可以实现这样的效果吗?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
您可以监听 点击 事件 document
它不是被点击元素的祖先或目标 #menucontainer
确保 .closest()
.
如果不是,那么被点击的元素就在外面 #menucontainer
,你可以安全地隐藏它。
$(document).click(function(event) {
var $target = $(event.target);
if(!$target.closest('#menucontainer').length &&
$('#menucontainer').is(":visible")) {
$('#menucontainer').hide();
}
});
如果您打算关闭菜单并希望停止监听事件,您也可以在事件监听器之后进行清理。此函数将仅清理新创建的监听器,并保留 上的任何其他点击监听器 document
。使用 ES2015 语法:
export function hideOnClickOutside(selector) {
const outsideClickListener = (event) => {
const $target = $(event.target);
if (!$target.closest(selector).length && $(selector).is(':visible')) {
$(selector).hide();
removeClickListener();
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener);
}
document.addEventListener('click', outsideClickListener);
}
对于那些不想使用 jQuery 的人。以下是使用普通 vanillaJS (ECMAScript6) 编写的上述代码。
function hideOnClickOutside(element) {
const outsideClickListener = event => {
if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null
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 可以在这里找到: Element.closest()
如果您希望用户能够在元素内部单击并拖动,然后在元素外部释放鼠标,而不关闭元素:
...
let lastMouseDownX = 0;
let lastMouseDownY = 0;
let lastMouseDownWasOutside = false;
const mouseDownListener = (event: MouseEvent) => {
lastMouseDownX = event.offsetX;
lastMouseDownY = event.offsetY;
lastMouseDownWasOutside = !$(event.target).closest(element).length;
}
document.addEventListener('mousedown', mouseDownListener);
并且 outsideClickListener
:
const outsideClickListener = event => {
const deltaX = event.offsetX - lastMouseDownX;
const deltaY = event.offsetY - lastMouseDownY;
const distSq = (deltaX * deltaX) + (deltaY * deltaY);
const isDrag = distSq > 3;
const isDragException = isDrag && !lastMouseDownWasOutside;
if (!element.contains(event.target) && isVisible(element) && !isDragException) { // or use: event.target.closest(selector) === null
element.style.display = 'none';
removeClickListener();
document.removeEventListener('mousedown', mouseDownListener); // Or add this line to removeClickListener()
}
}