我有一堆div完全位于彼此之上。当我将click事件绑定到所有这些事件时,只有顶部div响应。如何将事件发送到光标下的所有div?
答案 0 :(得分:3)
考虑到FelixKling建议使用document.elementFromPoint()
和Amberlamps的小提琴,并使用jQuery进行DOM交互,我最终得到了以下内容:
$divs = $("div").on('click.passThrough', function (e, ee) {
var $el = $(this).hide();
try {
console.log($el.text());//or console.log(...) or whatever
ee = ee || {
pageX: e.pageX,
pageY: e.pageY
};
var next = document.elementFromPoint(ee.pageX, ee.pageY);
next = (next.nodeType == 3) ? next.parentNode : next //Opera
$(next).trigger('click.passThrough', ee);
} catch (err) {
console.log("click.passThrough failed: " + err.message);
} finally {
$el.show();
}
});
<强> DEMO 强>
try/catch/finally
用于确保元素再次显示,即使发生错误。
两种机制允许点击事件通过或不通过:
click.passThrough
类似于event.stopPropagation()
。单独或组合,这些机制在控制“passThrough”行为的附着和传播方面提供了一些灵活性。例如,在DEMO中,尝试从“b”元素中删除类p
,并查看传播行为的变化。
目前,需要编辑代码以获得不同的应用程序级行为。一个更通用的解决方案是:
event.stopPropagation()
。这两个目标都可以通过在jQuery中建立clickPassthrough
事件来实现,具有潜在的“passThrough”行为,但实现这一目标还需要做更多的工作。也许有人想要去。
答案 1 :(得分:1)
这并不像你想象的那么容易。这是我提出的解决方案。我只在Chrome中测试过,而且我没有使用任何框架。
以下代码段仅用于向文档中的每个div
添加一个点击事件,在触发时输出其类名。
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++) {
divs[i].onclick = function() {
console.log("class clicked: " + this.className);
};
}
将click事件附加到body元素,以便我们的脚本注意到每个单击事件。
if(document.addEventListener) {
document.body.addEventListener("click", countDivs);
} else if(document.attachEvent) {
document.attachEvent("onclick", countDivs);
}
遍历您要检查的所有div(您可能希望在此处调整您喜欢的div范围)。生成他们的计算样式并检查鼠标坐标是否在div的位置加上其宽度和高度的范围内。当div是我们的源元素时,不要触发click事件,因为当时已经触发了click事件。
function countDivs(e) {
e = e || window.event;
for(var i = 0; i < divs.length; i++) {
var cStyle = window.getComputedStyle(divs[i]);
if(divs[i] !== e.target && e.pageX >= parseInt(cStyle.left) && e.pageX <= (parseInt(cStyle.left) + parseInt(cStyle.width)) && e.pageY >= parseInt(cStyle.top) && e.pageY <= (parseInt(cStyle.top) + parseInt(cStyle.height))) {
divs[i].click();
}
}
}
CSS:
.a, .b, .c {
position: absolute;
height: 100px;
width: 100px;
border: 1px #000 solid
}
.a {
top: 100px;
left: 100px;
}
.b {
top: 120px;
left: 120px;
}
.c {
top: 140px;
left: 140px;
}
HTML:
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
我还添加了jsFiddle
答案 2 :(得分:0)
一种简单的方法可以是使用elementFromPoint():
var clicks = 0,cursorPosition={};
$('div').click(function (e) {
if(typeof cursorPosition.X === 'undefined') {
cursorPosition.X = e.pageX;
cursorPosition.Y = e.pageY;
}
clicks++;
e.stopPropagation();
$(this).addClass('hided');
var underELEM = document.elementFromPoint(cursorPosition.X, cursorPosition.Y);
if (underELEM.nodeName.toUpperCase() === "DIV") $(underELEM).click();
else {
$('#clicks').html("Clicks: " + clicks);
$('.hided').removeClass('hided');
clicks=0;
cursorPosition = {};
}
});
答案 3 :(得分:0)
如果要绝对堆叠元素,将它们全部堆叠在已定位的容器中可能更简单,并处理来自此父级的事件。然后,您可以操纵其孩子,而无需进行任何衡量。