检测点击外部元素(香草JavaScript)

我已经在任何地方寻找一个好的解决scheme,但我找不到一个不使用jQuery的

是否有一个跨浏览器,正常的方式(没有怪异的黑客或容易打破代码),检测元素(可能会或可能没有孩子)以外的点击?

添加一个事件监听器来document并使用Node.contains()来查找事件的目标(是哪个点击最顶端的元素)是否在你指定的元素中。 它甚至可以在IE5中运行

 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) { //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> 

您需要处理文档级别的点击事件。 在事件对象中,你有一个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,但其中的一个父母是被监视的元素(我只是为此计数水平)。 你也可以有一个布尔variables,如果元素被find或不从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的想法;)

这个怎么样:

JSBBIN-演示

 document.onclick = function(event){ var hasParent = false; for(var node = event.target; node != document.body; node = node.parentNode) { if(node.id == 'div1'){ hasParent = true; break; } } if(hasParent) alert('inside'); else alert('outside'); } 

点击外面隐藏元素我通常应用这样简单的代码:

 var bodyTag = document.getElementsByTagName('body'); var element = document.getElementById('element'); function clickedOrNot(e) { if (e.target !== element) { // action in the case of click outside bodyTag[0].removeEventListener('click', clickedOrNot, true); } } bodyTag[0].addEventListener('click', clickedOrNot, true);