Skip to main content

Bug Tracker

Side navigation

#12652 closed bug (notabug)

Opened October 04, 2012 12:44PM UTC

Closed October 04, 2012 01:40PM UTC

Last modified April 08, 2013 06:02PM UTC

Links with onclick handlers that return true break when invoked through jQuery

Reported by: Stijn de Witt Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: 1.8.2
Keywords: Cc:
Blocked by: Blocking:
Description

When you click a link from code using jQuery's click() method, and that link has an onclick handler that returns true, the default action of the link (navigate to the href) is not executed. This seems to me to be a bug in jQuery's event handling code.

I created a live example demonstrating the issue in JsFiddle:

http://jsfiddle.net/W5xzm/9/

Attachments (0)
Change History (17)

Changed October 04, 2012 01:40PM UTC by dmethvin comment:1

resolution: → notabug
status: newclosed

Not all browsers have a DOM .click() method that navigates to the link, so for consistent cross-browser behavior jQuery does not attempt to navigate when you trigger links manually. It's easy to get the desired behavior though. See the top comment at the docs page: http://api.jquery.com/trigger/

Changed October 05, 2012 08:23AM UTC by anonymous comment:2

The top comment advises binding an extra handler to navigate to the href, like so:

$('#someLink').bind('click', function() {

window.location.href = this.href;

return false;

});

Isn't that actually bad practice? Seems to me any handlers bound to the onclick of #someLink after this event handler was bound would never get fired because of the return false...

In any way, this behavior really surprised me.

You say that some browsers do not navigate to the href when you call click() on them... Do you have examples on that? I ask because that's exactly what I am doing in my code right now to work around jQuery's behavior. I am getting the native DOM element and calling click() on that directly. I might need to change that if any of the browsers we target don't actually support that...

Changed October 05, 2012 12:37PM UTC by dmethvin comment:3

You say that some browsers do not navigate to the href when you call click() on them

I didn't say that at all. I said "Not all browsers have a DOM .click() method". Try this on Safari for example: http://jsfiddle.net/vSZuy/

Changed November 17, 2012 01:37PM UTC by dmethvin comment:4

#12847 is a duplicate of this ticket.

Changed January 08, 2013 09:22AM UTC by Nao comment:5

I'm sorry, but... Why do you completely drop the event's default action (instead of trying to trigger it) if the element is seen to be an anchor and the event a click?

I understand the fact that it would fail on non-HTML5 compatible browsers such as Safari and earlier IEs, in fact I saw this by myself, but why drop it? Why not add a simple one-liner as a fallback?

Something like 'if (elem.href) location = elem.href'...

It's *way* better than forcing jQuery users to actually implement that one...

This report should be re-opened. (Couldn't find any more recent report with the same bug in it.)

Changed January 08, 2013 01:04PM UTC by dmethvin comment:6

This behavior has been consistent for 5 years. Changing it to execute the default action on just some browsers would break code expecting the old behavior.

Changed January 08, 2013 04:18PM UTC by Nao comment:7

Then perhaps it shouldn't be closed as "notabug", but as a "wontfix"...

And, more importantly, this behavior should be documented. I can't count the number of support questions I saw on Stackoverflow etc. regarding this issue.

BTW, can't read comments for the .trigger page (mentioned in the first comment here), because they seem to be disabled in the new jQuery API website... :-/

Changed January 09, 2013 08:41AM UTC by Nao comment:8

I forgot to point out a couple more arguments.

$('element')[0].click() works in all HTML5-compliant browsers.

$('element').click() should work on all browsers -- I think it was jQuery's mission to transparently provide the same experience across all browsers. It shouldn't *drop* a feature for newer browsers just for consistency with older browsers whose bugs jQuery doesn't want to fix.. (?)

Since jQuery 1.9 makes it pretty obvious (with their -currently broken- upgrade guide) that developers will HAVE to refactor some of their code to account for many deprecated or dropped features, perhaps this 'feature' should be moved to the migration plugin somehow, and fixed in the final version.

We're in 2013. What else can I say. Happy new year, happy new HTML ;)

Changed January 09, 2013 01:31PM UTC by dmethvin comment:9

$('element').click() should work on all browsers

It does not. Did you try the example http://jsfiddle.net/vSZuy/ on Safari 5.1, which is one of our supported browsers?

Changed January 09, 2013 06:39PM UTC by Nao comment:10

Of course it does not. When I said "should work", I meant that jQuery has always aimed to make JavaScript cross-browser without hassle. Heck, that's the reason most of us started using it... So there's no reason they would consciously break this particular setup of $('a').click(...), while even something like $('div').click() is accepted.

So, it's literally "should", not "will probably".

Changed January 09, 2013 07:09PM UTC by dmethvin comment:11

Sorry, what I meant was to make this statement and I wasn't clear:

The native DOM click method, $('element')[0].click(), does not work on all browsers. In particular, Safari does not support the DOM .click() method on link elements, making it impossible for jQuery to trigger a native click behavior if a developer says $('element').click() and the default is not prevented. This is why that special case existed in the first place.

This behavior has been the case throughout jQuery's existence, so at this point there is no doubt a lot of code that has come to expect it. Is there a course of action you can recommend that won't break existing code?

Changed January 09, 2013 11:04PM UTC by Nao comment:12

Safari does not support the DOM .click() method on link elements

I never said it did. I said all HTML5-compliant browsers did. Please re-read comment #5 where I think I covered it all. Safari 5 (and perhaps later) obviously do not support HTML5 entirely.

But, and again as I said before: if jQuery goes all the way to skipping the entire code block if (1) the element is an <a> tag AND (2) the event type is click (it seems to be pretty specific to me! And why not drop div clicks since they're not HTML4-compliant either?), then I don't see why the jQuery team can't simply add, AFTER that code block, a simple:

else if (elem.href)

location = elem.href;

The additional 'if' is just there in case href isn't defined, but since it's an anchor, I'm guessing it's always set. Anyway... Could also do 'else if (elem.href && elem.href != "#")' to avoid jumping to pseudo-links that aren't supposed to be followed. But to me it's a waste of extra bytes (and I'm obsessive about saving bytes.)

I can not find any 'real life' situation where a developer would actually expect jQuery to drop their call to $('a').click() when they do it. They would in fact expect it to work, wouldn't they...?

I'm just trying to be logical. If you also have a logical explanation for why jQuery shouldn't do this, then I'm all ears. Thanks for listening. Or reading, or whatever.

Changed January 09, 2013 11:18PM UTC by dmethvin comment:13

why not drop div clicks since they're not HTML4-compliant either

That's not a problem case. There is no DOM .click() method on a div.

I don't see why the jQuery team can't simply add, AFTER that code block, a simple: else if (elem.href) location = elem.href;

Certainly it *seems* like it should be that easy, I'd though about that myself. However, I've also learned that developers tend to get used to the current behavior and changing things can cause lots of problems.

Since 1.9/2.0 is on the verge of shipping this is not going into those releases. We have the luxury of leaving this ticket here and we can let others register their pro/con.

Changed January 10, 2013 01:13PM UTC by scottgonzalez comment:14

Replying to [comment:12 Nao]:

else if (elem.href) location = elem.href;

What if the link specifies a target? Also, how do various devices handle various protocols (mailto, tel, etc.)? I have a feeling the logic for the default action of a click is more complicated than you think.

Changed January 12, 2013 05:44PM UTC by Nao comment:15

I don't really see a valid use case where someone would have such a specific link type, and still have a script specifically do a .click() on them.

Anyway. I see there's no real interest from the jQuery team in fixing this. Fine. I fixed it on my side when I reported, I just thought it'd make more sense to have it fixed in jQuery.

Good luck for the upcoming versions.

Changed April 07, 2013 03:28AM UTC by gibson042 comment:16

https://github.com/jquery/jquery/pull/1223 doesn't fully solve your problem, but it does expose enough to do so with a small plugin.

Changed April 08, 2013 06:02PM UTC by Richard Gibson comment:17

Ref #12652: Allow overriding native .click() suppression

(cherry picked from commit 14b09ef98eb11aae04c028a3b3d7af116c7d2c20)

Changeset: a120bbbfae81daccf801fcf8deb0bc77d865e27f