1

Question:

HTML:

<div id="main">
    hello main 
    <div id="sub"> hello sub </div>
</div>

JS:

$("#main").on("click", function() {alert("main");});
$("#sub").on("click", function() {alert("sub");});

Here, when i click the "hello sub" text, two alerts -sub and main - are triggered while i want to see only "sub". How can i achieve this?

soleiljy
  • 1,121
  • 2
  • 13
  • 20

4 Answers4

2

You can use event.stopPropagation in sub event handler to stop propagation of event up the DOM hierarchy tree.

Live Demo

$("#main").on("click", function() {alert("main");});
$("#sub").on("click", function(event) {event.stopPropagation();alert("sub");});
Adil
  • 146,340
  • 25
  • 209
  • 204
1

In addition to stopping the propagation on the #sub element, you could instead check inside the event handler for #main if the clicked element was in fact #main if that's more convenient :

$("#main").on("click", function(e) {
    if (e.target === this)  alert("main");
});

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
0
$("#sub").on("click", function(e) { //pass in event as "e"
    e.stopPropagation(); //stop propagation from bubbling to the next element.
    alert("sub");
});
Ohgodwhy
  • 49,779
  • 11
  • 80
  • 110
0

The previous answers all work, but my preferred way is to check $(event.target).closest() for the non-handled child node in the container node's event handler, to avoid various gotchas. event.stopPropgation() prevents higher-level containers from seeing the event, which oftentimes ends up being needed. Checking e.target will fail if there's a nested element underneath sub that's clicked instead of sub directly. This approach avoids both issues:

$(".main").on("click", function (event) {
    if($(event.target).closest(".sub").length){
        return;
    }
    alert("main")    
});
$(".sub").on("click", function (event) {
    alert("sub");
});

Fiddle w/ example of a higher-level container that has an independent event handler.

http://jsfiddle.net/rH5vj/1/

AdamKG
  • 13,678
  • 3
  • 38
  • 46