检测点击外部元素(香草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);