admin管理员组

文章数量:1391925

Lets say we have a HTML structure like this

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

...and our goal is to have an event listener on the #container only ! So, we bind a listener (jQuery code)

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

That works of course, but my problem with this approach is that, since events usually bubble up, that listener will also fire if we actually click on #nested or #someElement. My current solution to only handle the click when the #container is clicked is to pare this with event.target

$("#container").on('click', function(event) {
    if(this === event.target) {
        alert("container was clicked");
    }
});

My question: Is that considered "best practice" ? Is there a better way with jQuery to acplish the same result "out of the box" ?

Example in action: /

Lets say we have a HTML structure like this

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

...and our goal is to have an event listener on the #container only ! So, we bind a listener (jQuery code)

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

That works of course, but my problem with this approach is that, since events usually bubble up, that listener will also fire if we actually click on #nested or #someElement. My current solution to only handle the click when the #container is clicked is to pare this with event.target

$("#container").on('click', function(event) {
    if(this === event.target) {
        alert("container was clicked");
    }
});

My question: Is that considered "best practice" ? Is there a better way with jQuery to acplish the same result "out of the box" ?

Example in action: http://jsfiddle/FKX7p/

Share Improve this question asked Sep 17, 2012 at 12:16 Andre MeinholdAndre Meinhold 5,3173 gold badges23 silver badges30 bronze badges 3
  • 3 IMO, this is the best practice. – VisioN Commented Sep 17, 2012 at 12:20
  • @jSang: Actually the inner elements don't have any listeners on a click. Is that considered best practice ? bind every element just to stop the propagation ? – Andre Meinhold Commented Sep 17, 2012 at 12:21
  • I don't see any better approach either, in fact, I was about to post that as an answer until I saw you already have that code. – Fabrício Matté Commented Sep 17, 2012 at 12:24
Add a ment  | 

3 Answers 3

Reset to default 2

An alternative way to prevent events from bubbling up is to use event.stopPropagation();

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

I think the advantage of using this approach is that if you want to attach another event to the nested div, you can just use

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

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

I'm not sure which one work's faster but it make sense that the next code will be better:

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

Alternative solution:

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

But your solution is better. jsfiddle/FKX7p/2/ (with return false) OR jsfiddle/FKX7p/3/ (using stopPropagation)

I prefer use return in your example (code bees easier to read):

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

本文标签: javascriptMastering event bubblingStack Overflow