我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
我有一些HTML菜单,当用户单击这些菜单的头部时,我会完全显示这些菜单。当用户在菜单区域外单击时,我希望隐藏这些元素。
jQuery是否可以实现这样的功能?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
当前回答
老实说,我不喜欢以前的任何解决方案。
要做到这一点,最好的方法是将“点击”事件绑定到文档,并比较该点击是否真的在元素之外(就像Art在建议中所说的那样)。
然而,您会遇到一些问题:您永远无法解除绑定,并且无法使用外部按钮打开/关闭该元素。
这就是为什么我编写了这个小插件(点击此处链接),以简化这些任务。能简单一点吗?
<a id='theButton' href="#">Toggle the menu</a><br/>
<div id='theMenu'>
I should be toggled when the above menu is clicked,
and hidden when user clicks outside.
</div>
<script>
$('#theButton').click(function(){
$('#theMenu').slideDown();
});
$("#theMenu").dClickOutside({ ignoreList: $("#theButton") }, function(clickedObj){
$(this).slideUp();
});
</script>
其他回答
这是一个更通用的解决方案,它允许监视多个元素,并动态地从队列中添加和删除元素。
它保存一个全局队列(autoCloseQueue)——一个对象容器,用于在外部单击时应关闭的元素。
每个队列对象键都应该是DOM元素id,值应该是一个具有2个回调函数的对象:
{onPress: someCallbackFunction, onOutsidePress: anotherCallbackFunction}
将其放入文档就绪回调中:
window.autoCloseQueue = {}
$(document).click(function(event) {
for (id in autoCloseQueue){
var element = autoCloseQueue[id];
if ( ($(e.target).parents('#' + id).length) > 0) { // This is a click on the element (or its child element)
console.log('This is a click on an element (or its child element) with id: ' + id);
if (typeof element.onPress == 'function') element.onPress(event, id);
} else { //This is a click outside the element
console.log('This is a click outside the element with id: ' + id);
if (typeof element.onOutsidePress == 'function') element.onOutsidePress(event, id); //call the outside callback
delete autoCloseQueue[id]; //remove the element from the queue
}
}
});
然后,当创建id为“menuscontainer”的DOM元素时,只需将此对象添加到队列:
window.autoCloseQueue['menuscontainer'] = {onOutsidePress: clickOutsideThisElement}
这是我解决问题的方法。
$(window).click(function (event) {
//To improve performance add a checklike
//if(myElement.isClosed) return;
var isClickedElementChildOfMyBox = isChildOfElement(event,'#id-of-my-element');
if (isClickedElementChildOfMyBox)
return;
//your code to hide the element
});
var isChildOfElement = function (event, selector) {
if (event.originalEvent.path) {
return event.originalEvent.path[0].closest(selector) !== null;
}
return event.originalEvent.originalTarget.closest(selector) !== null;
}
我认为最好的方法是这样做。
$(document).on("click", function(event) {
clickedtarget = $(event.target).closest('#menuscontainer');
$("#menuscontainer").not(clickedtarget).hide();
});
这种类型的解决方案很容易适用于多个菜单以及通过javascript动态添加的菜单。基本上,它只允许您单击文档中的任何位置,并检查您单击的元素,并选择最接近的“#菜单容器”。然后它会隐藏所有菜单容器,但不包括您单击的菜单容器。
不确定菜单是如何构建的,但可以在JSFiddle中复制我的代码。这是一个非常简单但功能全面的菜单/模式系统。您需要做的就是构建html菜单,代码将为您完成这项工作。
https://jsfiddle.net/zs6anrn7/
试试这个:
$('html').click(function(e) {
if($(e.target).parents('#menuscontainer').length == 0) {
$('#menuscontainer').hide();
}
});
https://jsfiddle.net/4cj4jxy0/
但请注意,如果单击事件无法到达html标记,则这将无法工作。(可能其他元素已停止传播())。
对于某些人来说,这可能是一个更好的解决方案。
$(".menu_link").click(function(){
// show menu code
});
$(".menu_link").mouseleave(function(){
//hide menu code, you may add a timer for 3 seconds before code to be run
});
我知道mouseleave不仅意味着在外面单击,还意味着离开该元素的区域。
一旦菜单本身位于menu_link元素内,那么单击或移动菜单本身应该不会有问题。