在委托事件处理程序的情况下,您可能会遇到这样的情况:
<ul>
<li data-id="1">
<span>Item 1</span>
</li>
<li data-id="2">
<span>Item 2</span>
</li>
<li data-id="3">
<span>Item 3</span>
</li>
<li data-id="4">
<span>Item 4</span>
</li>
<li data-id="5">
<span>Item 5</span>
</li>
</ul>
你的JS代码是这样的:
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target),
itemId = $target.data('id');
//do something with itemId
});
});
您很可能会发现 itemId 是undefined
,因为 LI 的内容包含在 a 中<span>
,这意味着<span>
可能是事件目标。你可以通过一个小检查来解决这个问题,如下所示:
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target).is('li') ? $(event.target) : $(event.target).closest('li'),
itemId = $target.data('id');
//do something with itemId
});
});
或者,如果您希望最大限度地提高可读性(同时避免不必要的 jQuery 包装调用重复):
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target),
itemId;
$target = $target.is('li') ? $target : $target.closest('li');
itemId = $target.data('id');
//do something with itemId
});
});
使用事件委托时,该.is()
方法对于验证您的事件目标(除其他外)是否确实是您所需要的非常宝贵。使用.closest(selector)
向上搜索 DOM 树,使用.find(selector)
(通常与 结合.first()
,如.find(selector).first()
)向下搜索。.first()
使用时不需要使用.closest()
,因为它只返回第一个匹配的祖先元素,而.find()
返回所有匹配的后代。