There are several ways to handle events in javascript / jQuery. Two of them:
- You can use the direct event handler on the object.
- You can use delegated event processing, where you handle a common event for the parent.
If you use the direct event handler on the object and the handlers of the processed events are not configured on the page, then there is no reason for e.stopPropagation() .
But if you have delegated event handlers that use distribution, you sometimes want to make sure that the higher level handler does not fire the current event.
In your specific example:
$(document.body).on('click', "a.ajaxLink", function(e){
This is a delegated event handler. It searches for any click event that propagates to the document.body object, but a.ajaxLink from the a.ajaxLink object. There are few advantages for e.stopPropagation() , because the event is almost completely distributed (it will also correspond to document , but if you also have a handler for e.stopPropagation() document object, then there is no reason for e.stopPropagation() in this handler.
If this makes sense, when you have a delegated top-level event handler (for example, the one in your example) and you have lower-level event handlers (either directly on objects or using delegated event processing, but at the level below the document.body e.stopPropagation() this case, if you want the lower-level event handler to receive the event, you would e.stopPropagation() in its handler so that the document.body handler would never see the event.
$("a.ajaxLink").click(function(e) { if (some condition) { // do something specific to this condition code here // stop propagation so the default behavior for click in document.body does not fire e.stopPropagation(); } })
Note. Using return false from the jQuery event handler fires both e.stopPropagation() and e.preventDefault() . But, if you are in a delegated event handler, e.preventDefault() does nothing, because the default behavior (if any) is already running when the target first saw the event. The default behavior occurs before the event propagates, so e.preventDefault() only works in event handlers directly on the target.
There is no noticeable performance degradation because you allow the event to bubble up, because these are user-level events, and they simply do not happen fast enough to make a difference, and it is not bubbling especially slowly when there are all intermediate objects. There are already special cases in the system where some events like mousemove can quickly occur to solve this problem. If you have a giant project with hundreds or thousands of event handlers, there are times when using delegated event processing is more efficient, and there are times when direct event handlers on real targets are more efficient. But apart from the gigantic scenarios, the performance difference is probably not noticeable.
Here is an example where bubbling / delegation is more efficient. You have a giant table with thousands of rows, and each row has two buttons (add / delete say). With delegated event handling, you can handle all the buttons in two simple event handlers that you attach to the table object (the common parent of the buttons). It will be much faster to install event handlers, rather than installing several thousand event handlers directly on each button. These delegated event handlers will also automatically work with the newly created rows / objects in the table. This is an ideal scenario for event handlers / event delegation. Please note that in this case there is no reason to stop the distribution / sparging.
Here's an example of where delegated event handlers are very inefficient. Suppose you have a good sized web page with hundreds of objects and event handlers. You can make each of the event handlers a delegated event handler attached to the document object. But here is what happens. Clicking occurs. There is no event handler on the actual object to bubble. In the end, it falls into the document object. A document object contains hundreds of event handlers. The event processing engine (jQuery in this case) should look at each of these event handlers and compare the selector in the delegated event handler for each of them with the original purpose of the event to see if they match. Some of these comparisons are not fast because they can be full-blown CSS selectors. He has to do this for hundreds of delegated events. This is bad for performance. This is why .live() in jQuery is deprecated because it worked that way. Instead, delegated event handlers should be located as close as possible to the target (the closest parent, which is practical given the circumstances). And, when there is no need for a delegated event handler, the handlers must be placed in the actual target, as this is most efficient at run time.
Return to the original question. There is no time when you want the bubbles to turn off altogether. As I described earlier in my answer, there are specific cases where an event handler located further down the tree wants to process the event and stop any delegated event handlers above in the DOM tree from processing this event. This is the time of e.stopPropatation() .
Here are a few other relevant posts with useful information on this topic (as was widely discussed earlier):
Why not take a Javascript event as a last resort?
Should all jquery events bind to $ (document)?
Does jQuery.on () work for items added after creating an event handler?
jQuery on () and stopPropagation ()
Best practice to avoid memory or performance issues associated with binding a large number of DOM objects to a click event
jQuery.live () vs .on () method to add click event after loading dynamic html