Return false has changed in jquery 1.4.3

Neeraj Singh

Neeraj Singh

October 25, 2010

jQuery 1.4.3 was recently released. If you upgrade to jQuery 1.4.3 you will notice that the behavior of return false has changed in this version. First let's see what return false does.

return false

1$("a").click(function () {
2  console.log("clicked");
3  return false;
4});

First ensure that above code is executed on domready. Now if I click on any link then two things will happen.

1e.preventDefault() will be called .
2e.stopPropagation() will be called .

e.preventDefault()

As the name suggests, calling e.preventDefault() will make sure that the default behavior is not executed.

1<a href='www.google.com'>click me</a>

If above link is clicked then the default behavior of the browser is to take you to www.google.com. However by invoking e.preventDefault() browser will not go ahead with default behavior and I will <strong>not</strong> be taken to www.google.com.

e.stopPropagation

When a link is clicked then an event "click event" is created. And this event bubbles all the way up to the top. By invoking e.stopPropagation I am asking browser to not to propagate the event. In other words the event will stop bubbling.

1<div class="first">
2  <div class="two">
3    <a href="www.google.com">click me</a>
4  </div>
5</div>

If I click on "click me" then "click event" will start bubbling. Now let's say that I catch this event at .two and if I call e.stopPropagation() then this event will never reach to .first .

e.stopImmediatePropagation

First note that you can bind more than one event to an element. Take a look at following case.

1<a class="one">one</a>

I am going to bind three events to the above element.

1$("a").bind("click", function (e) {
2  console.log("first");
3});
4
5$("a").bind("click", function (e) {
6  console.log("second");
7  e.stopImmediatePropagation();
8});
9
10$("a").bind("click", function (e) {
11  console.log("third");
12});

In this case there are three events bound to the same element. Notice that second event binding invokes e.stopImmediatePropagation() . Calling e.stopImmediatePropagation does two things.

Just like stopPropagation it will stop the bubbling of the event. So any parent of this element will not get this event.

However stopImmdiatePropagation stops the event bubbling even to the siblings. It kills the event right then and there. That's it. End of the event.

Once again calling stopPropagation means stop this event going to parent. And calling stopImmediatePropagation means stop passing this event to other event handlers bound to itself.

If you are interested here is link to DOM Level 3 Events spec.

Back to original problem

Now that I have described what preventDefault, stopPropagation and stopImmediatePropagation does lets see what changed in jQuery 1.4.3.

In jQuery 1.4.2 when I execute "return false" then that action was same as executing:

1e.preventDefault();
2e.stopPropagation();
3e.stopImmediatePropagation();

Now e.stopImmediatePropagation internally calls e.stopPragation but I have added here for visual clarity.

Fact that return false was calling e.stopImmeidatePropagation was a bug. Get that. It was a bug which got fixed in jquery 1.4.3.

So in jquery 1.4.3 e.stopImmediatePropagation is not called. Checkout this piece of code from events.js of jquery code base.

1if (ret !== undefined) {
2  event.result = ret;
3  if (ret === false) {
4    event.preventDefault();
5    event.stopPropagation();
6  }
7}

As you can see when return false is invoked then e.stopImmediatePropagation is <strong>not</strong> called.

It gets complicated with live and a bug in jQuery 1.4.3

To make the case complicated, jQuery 1.4.3 has a bug in which e.preventStopImmediatePropagation doest not work. Here is a link to this bug I reported.

To understand the bug take a look at following code:

1<a href='' class='first'>click me</a>
2
3$('a.first').live('click', function(e){
4    alert('hello');
5    e.preventDefault();
6    e.stopImmediatePropagation();
7});
8
9$('a.first').live('click', function(){
10    alert('world');
11});

Since I am invoking e.stopImmediatePropagation I should never see alert world. However you will see that alert if you are using jQuery 1.4.3. You can play with it here .

This bug has been fixed as per this commit . Note that the commit mentioned was done after the release of jQuery 1.4.3. To get the fix you will have to wait for jQuery 1.4.4 release or use jQuery edge.

I am using rails.js (jquery-ujs). What do I do?

As I have shown "return false" does not work in jQuery 1.4.3 . However I would have to like have as much backward compatibility in jquery-ujs as much possible so that the same code base works with jQuery 1.4 through 1.4.3 since not every one upgrades immediately.

This commit should make jquery-ujs jquery 1.4.3 compatible. Many issues have been logged at jquery-ujs and I will take a look at all of them one by one. Please do provide your feedback.

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.