Reputation: 11079
As we know, returning false
from a DOM event handler will stop the propagation of the event. But I recently discovered that the behavior of different elements varies with respect to this event. For example, consider the following:
<div id="container">
<input type="checkbox" name="foo" value="1" /> Check me!
<br />
<select>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<br />
<input type="text" size="30" />
</div>
The surrounding container has a click handler that returns false:
$('#container').click(function(e) {
$('#clicks').append('<span>clicked</span>');
return false;
});
Within the div
, I can still click on the text box and enter text, and can still click on the dropdown to change its value. But clicking on the checkbox does nothing (actually, that's not quite true - it checks the box, fires the handler, then unchecks it). jsfiddle here: http://jsfiddle.net/4ncaq/
This behavior is consistent across browsers so I assume it's by design. But what exactly is the rule that's at work here? How can I know how other kinds of elements might behave in this type of scenario?
Upvotes: 4
Views: 923
Reputation: 3097
When you click an element, the event will continue propagating the event until some handler decides to cancel the propagation. In this case, when you click the checkbox, it will raise the event for the <input>
first and then propagate to #container
where you are stopping propagation.
If you want to cancel the propagation from input elements such as checkboxes or textareas you should bind to their click
event and stop propagation at that point.
Edited
return false
also cancels the default action for the original target element. Checkboxes, links, radio buttons are some of the elements where the default click action is cancelable. The default action for the click event in a checkbox toggles the value of the checkbox while there is no default click action for the select which means it does not get cancelled.
I've tried to find a list of default actions without luck but you can check the links at Is there a standard resource for the "default action" of HTML elements?.
Upvotes: 2
Reputation: 2378
What you are seeing is propagation, events 'bubble' up the DOM, so when you click your checkbox it is actually firing the click event on #container (as well as any events you might have bound to the input or other parent elements).
Using return false like this is ambiguous because it is doing 3 things at once, when you most likely only want it to do one. It prevents the default functionality, halts propagation and stops further execution.
It is better practice to be specific and use the methods from the event object to prevent the default action or stop bubbling.
event.preventDefault() will stop things like loading the href from an anchor click, stopping a checkbox from being checked etc.
event.stopPropagation() will cancel propagation, this is useful for situations like your example - http://jsfiddle.net/4ncaq/1/
The other problem with return false is that it may not be executed, a common mistake I see people make in jQuery is having a click event on an anchor with an $.ajax() request followed by return false to stop the browser from loading the linked page. In this scenario, if there is an error coming from ajax() (not a response error, a jQuery error - usually a misspelt param or something) it will never hit return false; and the browser will load the linked page. Using e.preventDefault() entirely removes this problem.
Upvotes: 4