在委托事件处理程序的情况下,您可能会有类似以下内容:
<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
    });
});
undefined由于LI的内容包装在中<span>,您很有可能会发现itemId为,这意味着<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()返回所有匹配的后代。