我有以下标记:
<ul>
<li class="tgt"><img src="http://placehold.it/48x48" width="48px" height="48px"></li>
<li class="tgt"><img src="http://placehold.it/48x48" width="48px" height="48px"></li>
<li class="tgt"><img src="http://placehold.it/48x48" width="48px" height="48px"></li>
</ul>
来自小提琴的代码:
$('.tgt').on('click', function (e) {
if ($(e.target).hasClass('tgt')) {
$(e.target).addClass('active');
}
});
我使用jquery的事件委托将一个单击处理程序附加到所有.tgt元素。出于某种原因,如果我点击图像,事件不会冒泡到li。而是将事件目标显示为图像。
这是一个小提琴: http://jsfiddle.net/CgC4V/
为什么事件没有冒泡到li.tgt?
答案 0 :(得分:9)
事件 冒泡,但您使用e.target
测试的目标元素是实际点击的元素,如下所示: http://jsfiddle.net/CgC4V/1/
这就是事件冒泡应该起作用的方式 - 如果事件没有冒泡,那么附加到li元素的处理程序就不会被触发。
您可以使用this
来引用所点击的li:
$('.tgt').on('click', function (e) {
$('.active').removeClass('active');
if ($(this).hasClass('tgt')) {
$(this).addClass('active');
}
});
您可能不需要测试该元素是否具有tgt
类,因为您已经知道它必须是最初具有该类的li元素之一。
演示:http://jsfiddle.net/CgC4V/3/
评论更新:
“我是否应该访问jquery.event.currentTarget?在上下文不是jquery元素的情况下怎么办?jQuery.event的哪个属性引用了正确的元素?”
是的,event.currentTarget
会为您提供正确的元素。 “通常”,对于您显示的代码,event.currentTarget
与this
相同,但是如果您要做某些事情来改变this
的值(例如,如果您已使用$.proxy()
或Function.prototype.bind()
),然后event.currentTarget
将为您提供正确的元素。
另请注意,有时event.currentTarget
将与event.target
相同(如果您未更改this
,则为this
) - 在您的示例中,如果您点击li元素的“点”而不是图像,那么目标就是li本身。
答案 1 :(得分:1)
$('img').on('click', function (e) {
if ($(e.target).parent('li').hasClass('tgt')) {
$(e.target).parent('li').addClass('active');
}
});
这会使img
成为实际目标,但仍会为整个列表项提供突出显示。
答案 2 :(得分:1)
e指的是事件,但是你想在点击obj时添加类,所以只需将$(e.target)更改为$(this)并且它应该有效:
$('.tgt').on('click', function (e) {
if ($(this).hasClass('tgt')) {
$(this).addClass('active');
}
});
答案 3 :(得分:1)
您需要使用$(this)
代替event.target
,因为$(this)
始终是<li>
本身,event.target
将指向图片如果图像是接收点击事件的DOM中最深的可用元素。
$('.tgt').on('click', function (e) {
if ($(this).hasClass('tgt')) {
$(this).addClass('active');
}
});
编辑以澄清:请考虑以下结果。
点击 <li>
后,不 <img>
:
$(this)
指向<li>
event.target
指向<li>
点击 <img>
时:
$(this)
指向<li>
event.target
指向<img>
这是因为,在接收点击事件的所有元素中,event.target
将始终指向DOM中最深的元素。但是,$(this)
将始终位于<li>
上,并会抓住点击的<img>
中出现的任何事件。