检测点击外部元素?

chu*_*ckg 13 javascript jquery dom

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

$('#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();
    });
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

我尝试了以下$('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 }
Run Code Online (Sandbox Code Playgroud)

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

Pao*_*ino 29

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

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

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

  • @Josh,e.target在上面的代码中应该使用jQuery事件,而不是IE特定的事件. (2认同)

Jos*_*ola 15

我很久以前写过这篇文章,在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!');
}
Run Code Online (Sandbox Code Playgroud)