Javascript 使用单个事件处理程序检测元素内部/外部的点击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4660633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect click inside/outside of element with single event handler
提问by Thomas
Suppose I have one div in my page. how to detect the user click on div content or outside of div content through JavaScript or JQuery. please help with small code snippet. thanks.
假设我的页面中有一个 div。如何通过 JavaScript 或 JQuery 检测用户点击 div 内容或 div 内容之外的内容。请帮忙处理小代码片段。谢谢。
Edit: As commented in one of the answers below, I only want to attach an event handler to my body, and also want to know which element was clicked upon.
编辑:如以下答案之一所述,我只想将事件处理程序附加到我的身体,还想知道点击了哪个元素。
回答by amosrivera
In JavaScript (via jQuery):
在 JavaScript 中(通过 jQuery):
$(function() {
$("body").click(function(e) {
if (e.target.id == "myDiv" || $(e.target).parents("#myDiv").length) {
alert("Inside div");
} else {
alert("Outside div");
}
});
})
#myDiv {
background: #ff0000;
width: 25vw;
height: 25vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myDiv"></div>
回答by KhalilRavanna
Here's a one liner that doesn't require jquery using Node.contains:
这是使用Node.contains不需要 jquery 的单行代码:
// Get arbitrary element with id "my-element"
var myElementToCheckIfClicksAreInsideOf = document.querySelector('#my-element');
// Listen for click events on body
document.body.addEventListener('click', function (event) {
if (myElementToCheckIfClicksAreInsideOf.contains(event.target)) {
console.log('clicked inside');
} else {
console.log('clicked outside');
}
});
If you're wondering about the edge case of checking if the click is on the element itself, Node.contains returns true for the element itself (e.g. element.contains(element) === true
) so this snippet should always work.
如果您想知道检查点击是否在元素本身上的边缘情况,Node.contains 为元素本身返回 true(例如element.contains(element) === true
),因此此代码段应该始终有效。
Browser support seems to cover pretty much everything according to that MDN page as well.
根据该 MDN 页面,浏览器支持似乎也涵盖了几乎所有内容。
回答by Phrogz
Using jQuery, and assuming that you have <div id="foo">
:
使用 jQuery,并假设您有<div id="foo">
:
jQuery(function($){
$('#foo').click(function(e){
console.log( 'clicked on div' );
e.stopPropagation(); // Prevent bubbling
});
$('body').click(function(e){
console.log( 'clicked outside of div' );
});
});
Edit: For a single handler:
编辑:对于单个处理程序:
jQuery(function($){
$('body').click(function(e){
var clickedOn = $(e.target);
if (clickedOn.parents().andSelf().is('#foo')){
console.log( "Clicked on", clickedOn[0], "inside the div" );
}else{
console.log( "Clicked outside the div" );
});
});
回答by RayOnAir
Rather than using the jQuery .parents
function (as suggested in the accepted answer), it's better to use .closest
for this purpose. As explained in the jQuery api docs, .closest
checks the element passed and all its parents, whereas .parents
just checks the parents.
Consequently, this works:
与其使用 jQuery.parents
函数(如已接受的答案中所建议的那样),不如.closest
用于此目的。如jQuery api docs 中所述,.closest
检查传递的元素及其所有父元素,而.parents
只检查父元素。因此,这有效:
$(function() {
$("body").click(function(e) {
if ($(e.target).closest("#myDiv").length) {
alert("Clicked inside #myDiv");
} else {
alert("Clicked outside #myDiv");
}
});
})
回答by buildsucceeded
What about this?
那这个呢?
<style type="text/css">
div {border: 1px solid red; color: black; background-color: #9999DD;
width: 20em; height: 40em;}
</style>
<script type="text/javascript">
function sayLoc(e) {
e = e || window.event;
var tgt = e.target || e.srcElement;
// Get top lef co-ords of div
var divX = findPosX(tgt);
var divY = findPosY(tgt);
// Workout if page has been scrolled
var pXo = getPXoffset();
var pYo = getPYoffset();
// Subtract div co-ords from event co-ords
var clickX = e.clientX - divX + pXo;
var clickY = e.clientY - divY + pYo;
alert('Co-ords within div (x, y): '
+ clickX + ', ' + clickY);
}
function findPosX(obj) {
var curleft = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curleft += obj.offsetLeft
obj = obj.offsetParent;
}
} else if (obj.x) {
curleft += obj.x;
}
return curleft;
}
function findPosY(obj) {
var curtop = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curtop += obj.offsetTop
obj = obj.offsetParent;
}
} else if (obj.y) {
curtop += obj.y;
}
return curtop;
}
function getPXoffset(){
if (self.pageXOffset) { // all except Explorer
return self.pageXOffset;
} else if (document.documentElement
&& document.documentElement.scrollTop) {// Explorer 6 Strict
return document.documentElement.scrollLeft;
} else if (document.body) { // all other Explorers
return document.body.scrollLeft;
}
}
function getPYoffset(){
if (self.pageYOffset) { // all except Explorer
return self.pageYOffset;
} else if (document.documentElement
&& document.documentElement.scrollTop) {// Explorer 6 Strict
return document.documentElement.scrollTop;
} else if (document.body) { // all other Explorers
return document.body.scrollTop;
}
}
</script>
<div onclick="sayLoc(event);"></div>
(from http://bytes.com/topic/javascript/answers/151689-detect-click-inside-div-mozilla, using the Google.)
(来自http://bytes.com/topic/javascript/answers/151689-detect-click-inside-div-mozilla,使用 Google。)
回答by Alex Nikulin
This question can be answered with X and Y coordinates and without JQuery:
这个问题可以用 X 和 Y 坐标而不是 JQuery 来回答:
var isPointerEventInsideElement = function (event, element) {
var pos = {
x: event.targetTouches ? event.targetTouches[0].pageX : event.pageX,
y: event.targetTouches ? event.targetTouches[0].pageY : event.pageY
};
var rect = element.getBoundingClientRect();
return pos.x < rect.right && pos.x > rect.left && pos.y < rect.bottom && pos.y > rect.top;
};
document.querySelector('#my-element').addEventListener('click', function (event) {
console.log(isPointerEventInsideElement(event, document.querySelector('#my-any-child-element')))
});
回答by Labib Muhammad Jamal
For bootstrap 4 this works for me.
对于引导程序 4,这对我有用。
$(document).on('click', function(e) {
$('[data-toggle="popover"],[data-original-title]').each(function() {
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide')
}
});
});
working demo on jsfiddle link: https://jsfiddle.net/LabibMuhammadJamal/jys10nez/9/
jsfiddle 链接上的工作演示:https://jsfiddle.net/LabibMuhammadJamal/jys10nez/9/
回答by Santo Boldi?ar
In vanilla javaScript - in ES6
在 vanilla javaScript 中 - 在 ES6 中
(() => {
document.querySelector('.parent').addEventListener('click', event => {
alert(event.target.classList.contains('child') ? 'Child element.' : 'Parent element.');
});
})();
.parent {
display: inline-block;
padding: 45px;
background: lightgreen;
}
.child {
width: 120px;
height:60px;
background: teal;
}
<div class="parent">
<div class="child"></div>
</div>
回答by rbansal
If you want to add a click listener in chrome console, use this
如果要在 Chrome 控制台中添加点击侦听器,请使用此
document.querySelectorAll("label")[6].parentElement.onclick = () => {console.log('label clicked');}
回答by Andre
Instead of using the body you could create a curtain with z-index
of 100 (to pick a number) and give the inside element a higher z-index
while all other elements have a lower z-index than the curtain.
您可以创建一个z-index
100的窗帘(选择一个数字),而不是使用主体,并赋予内部元素更高的值,z-index
而所有其他元素的 z-index 比窗帘低。
See working example here: http://jsfiddle.net/Flandre/6JvFk/
请参阅此处的工作示例:http: //jsfiddle.net/Flandre/6JvFk/
jQuery:
jQuery:
$('#curtain').on("click", function(e) {
$(this).hide();
alert("clicked ouside of elements that stand out");
});
CSS:
CSS:
.aboveCurtain
{
z-index: 200; /* has to have a higher index than the curtain */
position: relative;
background-color: pink;
}
#curtain
{
position: fixed;
top: 0px;
left: 0px;
height: 100%;
background-color: black;
width: 100%;
z-index:100;
opacity:0.5 /* change opacity to 0 to make it a true glass effect */
}