我有一些HTML菜单,当用户单击这些菜单的标题时,它们会完整显示。 当用户在菜单区域之外单击时,我想隐藏这些元素。
jQuery可能会发生这种情况吗?
$("#menuscontainer").clickOutsideThisElement(function() {
// Hide the menus
});
#1楼
将单击事件侦听器挂在文档上。 在事件侦听器内部,您可以查看事件对象 ,特别是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");
}
});
#2楼
这完全适合我!
$('html').click(function (e) {
if (e.target.id == 'YOUR-DIV-ID') {
//do something
} else {
//do something
}
});
#3楼
这里的其他解决方案对我不起作用,因此我不得不使用:
if(!$(event.target).is('#foo'))
{
// hide menu
}
#4楼
如果您正在为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;}
#5楼
检查窗口单击事件目标(只要没有在其他任何地方捕获,它应该传播到窗口),并确保它不是任何菜单元素。 如果不是,那么您就在菜单之外。
或检查单击的位置,然后查看它是否包含在菜单区域中。
#6楼
注意:应该避免使用
stopEventPropagation()
,因为它会破坏DOM中的正常事件流。 有关更多信息,请参见本文 。 考虑改用此方法
将单击事件附加到关闭窗口的文档主体。 将单独的click事件附加到容器,以停止传播到文档主体。
$(window).click(function() {
//Hide the menus if visible
});
$('#menucontainer').click(function(event){
event.stopPropagation();
});
#7楼
我有一个类似于Eran的示例的应用程序,除了在打开菜单时将click事件附加到主体上。
$('#menucontainer').click(function(event) {
$('html').one('click',function() {
// Hide the menus
});
event.stopPropagation();
});
有关jQuery的one()
函数的更多信息
#8楼
与其使用流程中断,模糊/聚焦事件或任何其他棘手的技术,只需将事件流程与元素的亲属关系相匹配:
$(document).on("click.menu-outside", function(event){
// Test if target and it's parent aren't #menuscontainer
// That means the click event occur on other branch of document tree
if(!$(event.target).parents().andSelf().is("#menuscontainer")){
// Click outisde #menuscontainer
// Hide the menus (but test if menus aren't already hidden)
}
});
要删除外部点击事件监听器,只需:
$(document).off("click.menu-outside");
#9楼
$("#menuscontainer").click(function() {
$(this).focus();
});
$("#menuscontainer").blur(function(){
$(this).hide();
});
对我有用。
#10楼
作为变体:
var $menu = $('#menucontainer');
$(document).on('click', function (e) {
// If element is opened and click target is outside it, hide it
if ($menu.is(':visible') && !$menu.is(e.target) && !$menu.has(e.target).length) {
$menu.hide();
}
});
停止事件传播没有问题,并且更好地支持同一页面上的多个菜单,在第一个菜单处于打开状态时单击第二个菜单将使stopPropagation解决方案中的第一个菜单保持打开状态。
#11楼
将clickoutside处理程序(WLOG)绑定到元素时,将发生以下情况:
- 将该元素添加到一个数组,该数组包含带有clickoutside处理程序的所有元素
- ( 命名空间的 ) 单击处理程序已绑定到文档(如果尚未存在)
- 在文档中的任何单击上, 都会为该数组中与click -events目标不相等或为父的那些元素触发clickoutside事件
- 此外, clickoutside事件的event.target设置为用户单击的元素(因此,您甚至知道用户单击了什么,而不仅仅是他在外部单击了)
因此,不会停止任何事件的传播,并且可以使用外部处理程序在元素“上方”使用其他单击处理程序。
#12楼
解决方案1
与其使用event.stopPropagation()可能会有一些副作用,不如定义一个简单的标志变量并添加一个if
条件。 我对此进行了测试,并且正常工作,没有stopPropagation的任何副作用:
var flag = "1";
$('#menucontainer').click(function(event){
flag = "0"; // flag 0 means click happened in the area where we should not do any action
});
$('html').click(function() {
if(flag != "0"){
// Hide the menus if visible
}
else {
flag = "1";
}
});
解决方案2
只要一个简单的if
条件:
$(document).on('click', function(event){
var container = $("#menucontainer");
if (!container.is(event.target) && // If the target of the click isn't the container...
container.has(event.target).length === 0) // ... nor a descendant of the container
{
// Do whatever you want to do when click is outside the element
}
});
#13楼
您可以侦听document
上的click事件,然后使用.closest()
来确保#menucontainer
不是其祖先,也不是clicked元素的目标。
如果不是,则单击的元素在#menucontainer
外部,您可以安全地隐藏它。
$(document).click(function(event) {
$target = $(event.target);
if(!$target.closest('#menucontainer').length &&
$('#menucontainer').is(":visible")) {
$('#menucontainer').hide();
}
});
编辑– 2017-06-23
如果您打算关闭菜单并想停止监听事件,则还可以在事件监听器之后进行清理。 此功