检测点击外部元素(vanilla JavaScript)

新手上路,请多包涵

我到处都在寻找一个好的解决方案,但我找不到一个 不使用 jQuery 的解决方案。

是否有一种跨浏览器的正常方式(没有奇怪的黑客攻击或容易破解的代码)来检测元素外部的点击(可能有也可能没有孩子)?

原文由 oxygen 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 440
2 个回答

添加事件侦听器 document 并使用 Node.contains() 来查找事件的目标(最内层点击的元素)是否在您指定的元素内。它甚至在 IE5 中工作

const specifiedElement = document.getElementById('a')

// I'm using "click" but it works with any event
document.addEventListener('click', event => {
  const isClickInside = specifiedElement.contains(event.target)

  if (!isClickInside) {
    // The click was OUTSIDE the specifiedElement, do something
  }
})

 var specifiedElement = document.getElementById('a');

//I'm using "click" but it works with any event
document.addEventListener('click', function(event) {
  var isClickInside = specifiedElement.contains(event.target);
  if (isClickInside) {
    alert('You clicked inside A')
  } else {
    alert('You clicked outside A')
  }
});
 div {
  margin: auto;
  padding: 1em;
  max-width: 6em;
  background: rgba(0, 0, 0, .2);
  text-align: center;
}
 Is the click inside A or outside?
<div id="a">A
  <div id="b">B
    <div id="c">C</div>
  </div>
</div>

原文由 fregante 发布,翻译遵循 CC BY-SA 4.0 许可协议

您需要在文档级别处理点击事件。在事件对象中,您有一个 target 属性,即被单击的最内层 DOM 元素。有了这个,你就可以检查它自己并沿着它的父元素向上移动直到文档元素,如果它们中的一个是你监视的元素。

请参阅 jsFiddle 上的示例

document.addEventListener("click", function (e) {
  var level = 0;
  for (var element = e.target; element; element = element.parentNode) {
    if (element.id === 'x') {
      document.getElementById("out").innerHTML = (level ? "inner " : "") + "x clicked";
      return;
    }
    level++;
  }
  document.getElementById("out").innerHTML = "not x clicked";
});

与往常一样,由于 addEventListener/attachEvent,这不是跨浏览器兼容的,但它是这样工作的。

单击一个孩子,而不是 event.target,但它的父母之一是被监视的元素(我只是为此计算级别)。如果元素是否找到,您可能还有一个布尔变量,用于不从 for 子句内部返回处理程序。我的示例仅限于处理程序仅在没有匹配项时完成。

添加跨浏览器兼容性,我通常这样做:

 var addEvent = function (element, eventName, fn, useCapture) {
  if (element.addEventListener) {
    element.addEventListener(eventName, fn, useCapture);
  }
  else if (element.attachEvent) {
    element.attachEvent(eventName, function (e) {
      fn.apply(element, arguments);
    }, useCapture);
  }
};

这是用于附加事件侦听器/处理程序的跨浏览器兼容代码,包括在 IE 中重写 this 成为元素,就像 jQuery 对其事件处理程序所做的那样。有很多争论要记住一些 jQuery ;)

原文由 metadings 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏