jQuery: Event Bubbling and how "click", "live.click", "stopPropagation", and "return false" work together
I will have couples scenario here. Please help me
Here is the base case: http://jsfiddle.net/2zsLy/9/
When I click Click Me
, both alert box and Another Paragraph
come out. This is expected since the click event bubble up to the parent container, which is body
. Now start my questions
1) http://jsfiddle.net/2zsLy/10/
How come adding return false
to my live.click
does not stop the click event from bubble up. From the example, the live.click bubble up and trigger the alert box. I thought the documentation said that return false will stop the live event from bubble.
2) http://jsfiddle.net/2zsLy/11/
Now, I change the click event in body
to live.click
and it fix the problem -> the click event does not bubble up (hence no alert box is shown). Why does live.click
work and click
does not.
3) http://jsfiddle.net/2zsLy/13/
I think the documentation clearly said that calling event.stopPropagation()
will not stop the bubbling up from occurring, well I just did. I use event.stopPropagation()
expec开发者_StackOverflow中文版ting that it will still trigger my alert box, but it does not. Why?
NOTE: for the answer of the first two question, see justkt
answers. For the answer to the last question, see Squeegy
answer and his reply.
Answers to your questions can be found in the event.stopPropagation() docs.
With regards to live('click') versus 'click' and bubbling:
Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events. Similarly, events handled by .delegate() will always propagate to the element to which they are delegated; event handlers on any elements below it will already have been executed by the time the delegated event handler is called.
So what you are seeing is expected behavior. live('click') won't stop bubbling. The same is true of the now-preferred .delegate().
This answer describes extensively the problems of stopping propegation when using .live. See also the .live() documention:
The event bubbles up until it reaches the root of the tree, which is where .live() binds its special handlers by default.
- As of jQuery 1.4, event bubbling can optionally stop at a DOM element "context".
With regards to stopPropagation itself:
Kill the bubbling on the click event.
So stopPropagation() should prevent bubbling wherever return false; will, although not where it won't. It is preventDefault() that will not prevent bubbling. return false;
is effectively stopPropagation() and preventDefault().
In response to each jsfiddle example.
1) http://jsfiddle.net/2zsLy/10/
return false;
will not prevent events bound using live
or delegate
from bubbling up. The documentation explicitly says this about all bubbling, whether done with return false;
or with stopPropagation()
. So what happens is
- Click on
<p>
- Click bubbles to
<body>
, wherebody.click()
is triggered - Click bubbles to document root, where it matches
$(event.target).closest('p');
and solive('click')
is invoked - Return false happens, but body handler was invoked at step 2
2) http://jsfiddle.net/2zsLy/11/
In this case the event gets to the same spot (document root) and the return false stops the propagation to the further event bound via live
, which is on the body.
- Click on
<p>
- Click bubbles to
<body>
, but since body's handler is attached via live it is not invoked yet - Click bubbles to document root, where it matches
$(event.target).closest('p');
and solive('click')
is invoked - Return false happens
live('click')
is not invoked on the body due to the return false occurring.
3) http://jsfiddle.net/2zsLy/13/
stopPropagation()
is explicitly used to prevent bubbling, although it has the same restrictions return false;
does - so it won't prevent it in the case of a live('click')
event if there are click handlers bound via bind
.
Live events ALWAYS happen after bind events (like calling
click(fn)
). So return false does nothing here because$("body").click()
already happened. This is due to bubbling. The click happens on each parent of the element you clicked, triggering every click event. Only when it bubbles up to the root document, does it trigger any live events.In this example, you have 2 live events. So the event bubbles up to the document, and jQuery starts running any live events it finds that match your click. When it gets a
return false
it stops running any other live events. And live events declared first, run first. So you get the new paragraph, but nothing else since the alert was added to the live event stack AFTER thep
live click.It wont stop propogation for bind events, but the
event
argument is actually a jQuery event wrapper object, and I believe it knows aboutlive
. So it has a similar effect as returning false, it prevents the document click handler from executing any additional live events.
精彩评论