我准备了一个演示 HERE
我的问题:我正在尝试获取被点击元素的ID。 它始终返回CONTAINS其他元素的元素的ID:'外部'DIV父ID。
有趣的是,添加alert(...)
(在DEMO中取消注释)会导致两个警报!怎么样?为什么呢?
第一个指示重叠DIV的ID和第二个警报:ID“容器”。
如何获取确切点击元素的ID?
$(document).ready(function(){
$('div').each(function(){
$(this).click(function(){
$('#clicked_info').html($(this).attr('id'));
//alert($(this).attr('id')); // try THIS! wow!
});
});
});
是否也可以像alert
一样获取鼠标(点击)所有的元素ID,但没有alert
?
答案 0 :(得分:2)
由于您的点击处理程序应用于所有div,因此内部div和容器上都有一个单击处理程序。单击一次后,将执行两者的处理程序。如果你只想显示内部div,你可以通过这样做来阻止事件“冒泡”:
$('div').each(function(){
$(this).click(function(e){
e.stopPropagation();
$('#clicked_info').html($(this).attr('id'));
});
});
答案 1 :(得分:2)
原因是事件冒泡。在元素上触发事件时,会向其祖先元素通知事件。如果他们有任何事件处理程序绑定到该事件,它们也将被触发。
在这种情况下,单击#div3
会触发该元素上的处理程序(因此警告div3
),然后事件冒泡到container
元素,并触发处理程序在该元素上(因为您将处理程序绑定到所有div
元素)。由于container
处理程序是第二个触发的,因此放在#clicked_info
中的结果。 (div3
由第一个处理程序放在那里,但立即被替换。)
为了解决这个问题,有几个解决方案。我首选的解决方案是应用原始函数的id,即target
对象的event
属性:
$(this).click(function(event){
$('#clicked_info').html(event.target.id);
});
Modified example。请注意,我还简化了您的代码:each
调用是不必要的,因为click
绑定到选择中的每个元素。
我认为这种解决方案比停止传播更好,因为它不会阻止传播!传播通常很有用(这就是为什么它存在,毕竟),代码的其他一些方面可能依赖它。
答案 2 :(得分:1)
您正在为所有div元素分配click处理程序,因为div#container是返回元素id的所有div的父级。
将准备好的事件代码更改为:
$(document).ready(function(){
$(".cssInner").click(function(){
$('#clicked_info').html($(this).attr('id'));
//alert($(this).attr('id')); // try THIS! wow!
});
});
答案 3 :(得分:1)
我的猜测是因为click事件从内部div冒泡到包含div。该div的点击处理函数将在最后调用,并将覆盖#clicked_info
元素中的任何值。
如果只想调用内部div的处理程序,那么在附加单击处理程序时必须专门选择它们:
$(document).ready(function(){
$('div#container > div').each(function(){
$(this).click(function(){
$('#clicked_info').html($(this).attr('id'));
});
});
});
编辑或者,更简单,只需从处理程序函数返回false
即可。这将停止事件传播到包含元素。
答案 4 :(得分:0)
我认为这就是你的意思:
$(document).ready(function(){
$('div .cssInner').click(function(){
$('#clicked_info').html($(this).attr('id'));
//alert($(this).attr('id')); // try THIS! wow!
});
});
在这种情况下,您将click事件设置为仅在内部元素上发生!
答案 5 :(得分:0)
当已使用所需的点击选择器.each()
时,不需要$('div')
,指的是DOM中的任何'div'
元素。
默认情况下,click事件将沿DOM树向上传播 返回每个事件冒泡当前的元素ID。
提醒暂停执行冒泡,提醒当前元素ID,当满足肯定结果this.id
时,可以清楚地看到冒泡阶段。
在不使用alert
或console.log
的情况下(在页面上写入结果的示例中),所有先前检测到的ID将被最新注册的航班覆盖,从而仅使用最后一个注册ID。
我们假设我们有这个简单的HTML结构广告点击段落元素:
<div id="container">
Container element
<div id="box">
Box element
<p>Paragraph</p>
</div>
</div>
现在让我们使用event.stopPropagation()
阻止事件传播
$(function() {
$('div').click(function( ev ) {
ev.stopPropagation();
console.log( this.id ); // "box"
});
});
在上面的例子中,(!即使我们点击了p
元素),绑定到click事件的元素Selector也是$('div')
;进一步传播被阻止 - 返回所需的结果:"box"
。
以类似的方式使用上述代码,而是代之以event.target,我们可能会结束错误的结果:
$(function(){
$('div').click(function( ev ){
console.log( ev.target.id ); // ""
// ""
});
});
因为实际注册的event.target
元素是HTML 段落元素。
有两个嵌套的div
元素(#box
和#container
)console.log
结果通过两个DIV 结束冒泡事件 选择器两次记录相同(空)event.target
值(// "" // ""
)。
要准确查看当前冒泡的当前event.currentTarget元素,我们可以这样做:
console.log(ev.currentTarget.id+' '+ev.currentTarget.tagName); // "box DIV"
// "container DIV"
仍然会产生最后 DIV元素。
在浏览了上述所有结果之后,答案是停止/取消事件以使用event.stopPropagation()
冒泡DOM树并获取event.currentTarget.id
或简单地this.id
导致我们的jQuery选择器已经是期望的$('div')
元素。
现在知道事件冒泡了DOM和
获取所有元素ID的列表
我们只是允许事件传播,并将ID收集到一个数组中,如下例所示:
$(function(){
var allIDs = []; // Empty Array
$('div').on('mousedown', function( ev ){ //
allIDs.push( this.id ); // Push all bubbling DIVs ID into array!!
console.log( "All IDs: " + allIDs );
console.log( "Ev. bubbled Selector ID: " + this.id ); // First Parent
console.log( "Target ID: " + ev.target.id ); // The targeted one
}).on('mouseup', function(){
allIDs = []; // Reset array for further clicks inspections
});
});
<强> jsBin demo 强>