检测点击外部元素?

与此问题类似,但更进了一步。 我想检测一组项目之外的点击,我按以下方式处理:

$('#menu div').live('click', function() { // Close other open menu items, if any. // Toggle the clicked menu item. $('body').one('click', function(event) { // Hide the menu item. event.stopPropagation(); }); }); 

不幸的是,当另一个菜单项打开而另一个菜单项被点击时,这就像一个魅力,它需要两次点击才能打开第二个项目。 第一次单击隐藏第一个打开的菜单项,第二个单击显示第二个菜单项。

“正确”行为以下列方式起作用:

  • 单击菜单项将打开它。
  • 单击相同的菜单项(或其子项)将其关闭。
  • 单击另一个菜单项将关闭第一个,打开第二个菜单项。
  • 单击(打开)菜单项将关闭它们。

我尝试了以下代替上面的$('body').one()命令忽略菜单项的点击而收效甚微:

 // Captures click on menu items in spite of the not. $('*').not('#menu *').one('click', function() { // Hide menu } $('*:not(#menu)').one('click', function() { // Hide menu } 

一如既往,感谢您的帮助!

只需将身体点击处理程序移到外面,然后执行以下操作:

 $('body').bind('click', function(e) { if($(e.target).closest('#menu').length == 0) { // click happened outside of menu, hide any visible menu items } }); 

在评论中错误地指出e.target在IE中不起作用; 这不是真的,因为jQuery的Event对象在必要时修复了这些不一致(IE,Safari)。

很久以前我写过这个,在jQuery的辉煌岁月之前……

 function clickedOutsideElement(elemId) { var theElem = getEventTarget(window.event); while(theElem != null) { if(theElem.id == elemId) return false; theElem = theElem.offsetParent; } return true; } function getEventTarget(evt) { var targ = (evt.target) ? evt.target : evt.srcElement; if(targ != null) { if(targ.nodeType == 3) targ = targ.parentNode; } return targ; } document.onclick = function() { if(clickedOutsideElement('divTest')) alert('Outside the element!'); else alert('Inside the element!'); }