掌握事件冒泡

22

假设我们有以下HTML结构

<div id="container">
    <div id="nested">
        <span id="someElement"></span>
    </div>
</div>

我们的目标是仅在#container上绑定一个事件监听器!因此,我们绑定了一个监听器(使用jQuery代码)

$("#container").on('click', function(event) {
    alert("container was clicked");
});
当然,这行得通,但我对这种方法的问题在于,由于事件通常会冒泡,如果我们实际上点击了#nested#someElement,那么监听器也会触发。我目前的解决方案是仅在单击#container时处理单击事件,即将thisevent.target进行比较。
$("#container").on('click', function(event) {
    if(this === event.target) {
        alert("container was clicked");
    }
});

我的问题是:这被认为是“最佳实践”吗?有没有更好的使用jQuery来实现同样的结果而不需要额外的工作?

示例演示:http://jsfiddle.net/FKX7p/


3
我认为这是最佳实践。 - VisioN
@jSang:实际上,内部元素没有任何关于点击的监听器。这算是最佳实践吗?绑定每个元素只是为了停止传播? - Andre Meinhold
我也没有看到更好的方法,事实上,我正要把那个代码作为答案发布,直到我看到你已经有了那个代码。 - Fabrício Matté
3个回答

2
使用 event.stopPropagation() 是防止事件冒泡的另一种方法。
$("#container").on('click', function(event) {
    alert("container was clicked");
})
.children().on('click', function(event) {
    event.stopPropagation();
});

我认为使用这种方法的好处在于,如果您想将另一个事件附加到嵌套的div,您只需使用

$("#nested").on('click', function(event) {
    event.stopPropagation();
    // some action
});

$("#container").on('click', function(event) {
    alert("container was clicked");
});​

0

另一种解决方案:

$("#container").click(function(){
    alert("container was clicked");
}).children().click(function(e) {
    return false;
});

但是你的解决方案更好。 jsfiddle.net/FKX7p/2/(使用return false)或jsfiddle.net/FKX7p/3/(使用stopPropagation)

我更喜欢在你的示例中使用return(代码变得更容易阅读):

if(this !== event.target) return;

1
此外,在需要时请使用 event.CurrentTarget !== event.Target 而不是 this,因为在使用 jQuery.proxy 时可能会出现 this 的上下文更改:http://api.jquery.com/jQuery.proxy/ - Nope
另一种解决方案更糟糕,因为它添加了许多事件处理程序。 - naugtur
@naugtur 我同意你的观点,但在 on 函数出现之前,这个解决方案很流行。 - webdeveloper
如果 popular != good 那就是肯定的 ;) 比较 target 和 currentTarget 更好一些。(注意我没有给你一个 -1;主要是因为我曾经也做过这样的事情) - naugtur
@naugtur 是的,你说得对。我想指出没有人给我-1 :) - webdeveloper

0

我不确定哪个更快,但下面的代码更合理:

$("#container").click(function (e) {
    if (e.target.id && e.target.id !== "container") return false;
});

现在只检查标识符,对于复杂选择器,我看不到除了比较对象之外的其他方法。 - Ponpon32

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接