【发布时间】:2011-06-07 08:00:36
【问题描述】:
假设我的页面中有一个 div。如何通过 JavaScript 或 JQuery 检测用户点击 div 内容或 div 内容之外的内容。请帮助小代码sn-p。 谢谢。
编辑:正如以下答案之一所述,我只想将事件处理程序附加到我的正文,并且还想知道单击了哪个元素。
【问题讨论】:
标签: javascript jquery
假设我的页面中有一个 div。如何通过 JavaScript 或 JQuery 检测用户点击 div 内容或 div 内容之外的内容。请帮助小代码sn-p。 谢谢。
编辑:正如以下答案之一所述,我只想将事件处理程序附加到我的正文,并且还想知道单击了哪个元素。
【问题讨论】:
标签: javascript jquery
这是一个不需要 jquery 使用 Node.contains 的单行:
// 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');
}
});
如果您想知道检查点击是否在元素本身上的边缘情况,Node.contains 会为元素本身返回 true(例如 element.contains(element) === true),因此这个 sn-p 应该始终有效。
根据该 MDN 页面,浏览器支持似乎也涵盖了几乎所有内容。
【讨论】:
使用 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>
【讨论】:
"outside div"。
parents() 的使用激发了我更新我的答案,以使用更多的 jQuery 和更少的老式遍历。
$(e.target).parents("#myDiv").length,我记得,我发现的其他代码要复杂得多,甚至不能正常工作,非常感谢!
使用 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' );
});
});
编辑:对于单个处理程序:
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" );
});
});
【讨论】:
stopPropagation 的调用会阻止它冒泡。你可以在这里自己测试一下:jsfiddle.net/Qh2MN
.andSelf() 已被弃用。相反,只需将andSelf 替换为addBack,它应该可以正常工作。 api.jquery.com/andSelf
与其使用 jQuery .parents 函数(如已接受的答案中所建议的那样),不如为此目的使用 .closest。正如explained in the 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");
}
});
})
【讨论】:
这个怎么样?
<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>
(来自http://bytes.com/topic/javascript/answers/151689-detect-click-inside-div-mozilla,使用谷歌。)
【讨论】:
这个问题可以用 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')))
});
【讨论】:
在原生 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>
【讨论】:
对于 bootstrap 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')
}
});
});
jsfiddle 链接上的工作演示: https://jsfiddle.net/LabibMuhammadJamal/jys10nez/9/
【讨论】:
如果你想在 chrome 控制台中添加点击监听器,使用这个
document.querySelectorAll("label")[6].parentElement.onclick = () => {console.log('label clicked');}
【讨论】:
您可以创建一个 z-index 为 100(选择一个数字)的窗帘,而不是使用主体,并为内部元素赋予更高的 z-index,而所有其他元素的 z-index 都比窗帘低。
在此处查看工作示例:http://jsfiddle.net/Flandre/6JvFk/
jQuery:
$('#curtain').on("click", function(e) {
$(this).hide();
alert("clicked ouside of elements that stand out");
});
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 */
}
【讨论】: