11

Unfortunately, I'm working with some 3rd party javascript, which inserts links into my pages. Rather than just use these links as is, I want to use proxy elements, which, when clicked, trigger the click event on the 3rd party links.

The 3rd party links pack javascript into the href attribute, like this:

<a id="horribleLink" href="javascript:doSomething()">Click me</a>

My proxy element looks like this:

<button rel="horribleLink" class="linkProxy">No, click me</button>

And a bit of jQuery'd javascript to link them together:

$('button.linkProxy').click(function(){
    $('#' + $(this).attr('rel')).click();
});

Now, this works perfectly if the 3rd party link is just a standard link (<a id="horribleLink" href="http://www.google.com">Click</a>), or a slightly less horrible onclick (<a href="#" id="horribleLink" onclick="doSomething()">Click</a>), but when the javascript is inside the href attribute, triggering 'click' does nothing at all.

Can anyone tell me why, and if there's a reasonable workaround?

Updated As Millimetric said, the root cause looks to be that browsers prevent 'faking clicks' on anchors - I've removed my 'standard link' example, as that's another situation that doesn't work. The onclick handler does work, though, as you'd expect.

Ben Hull
  • 7,524
  • 3
  • 36
  • 56

5 Answers5

11

The accepted answer here goes into a little depth as to "why this is happening": Can I call jquery click() to follow an <a> link if I haven't bound an event handler to it with bind or click already?. Basically, it seems you can't do a click() on a link because the browser doesn't support fake clicking.

One Work-around:

If you set location.href for those cases, it works:

$('button.linkProxy').click(function(){
    location.href = $('#' + $(this).attr('rel')).attr('href');
});

Working fiddle: http://jsfiddle.net/uv29x/3/

Two Work-around:

You could just get the href of those links and do an eval() on them, right?

Community
  • 1
  • 1
Milimetric
  • 13,411
  • 4
  • 44
  • 56
  • I realize this is awful in terms of security, but the setup kinda forces you to do it I think. – Milimetric Aug 03 '11 at 13:38
  • That's the workaround I've got at the moment - it works fine, but I'd really like to understand what's going on, too. – Ben Hull Aug 03 '11 at 13:45
  • 3
    The accepted answer here goes into a little depth: http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-handl. Basically, it seems you can't do a `click()` on a link because the browser doesn't support fake clicking. – Milimetric Aug 03 '11 at 13:56
  • I'm accepting this answer, mainly for the comment above. I think I'll still use eval instead of location.href, but both workarounds are equally good(bad/ugly)! Thanks for your help! – Ben Hull Aug 03 '11 at 14:09
  • np, I'll edit that comment into the body as it does address your initial question better. – Milimetric Aug 03 '11 at 14:10
  • That being said, I have this feeling that `eval` is worse than `location.href = `. I don't know why as this is a bit above my pay grade. Jon Skeet? John Resig? – Milimetric Aug 03 '11 at 14:14
  • 1
    Third work around: http://jsfiddle.net/FKaYR/ (injecting `
    ` into the document, setting its action) though it's very much like changing the `location.href` thus only giving it as comment.
    – Shadow The GPT Wizard Aug 03 '11 at 14:22
  • 2
    As far as I can tell, eval() is no worse from a security point of view than a javascript: href attribute. Anyone who can pass in something nasty to eval could just as easily re-write the href attribute and have their code executed that way. Both methods have the same privileges, I think. – Ben Hull Aug 03 '11 at 22:49
  • +1 Beejamin. Just go the debugger and inject whatever you want. Yes it is hideous to use within more or less any other language, but in js it's fair game, if a little slow. – lededje Apr 16 '13 at 11:19
  • Weird, fiddle used to work :) You should make a new one with the sample code and edit the answer. That's what wikis are for! – Milimetric Feb 17 '17 at 16:05
4

Set window.location to the href value.

$('button.linkProxy').click(function(){
    window.location = $('#'+$(this).attr('rel')).attr('href');
});

DEMO: http://jsfiddle.net/dmSUm/

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
2

I'd just finished typing this up when I saw Milimetric's answer . Here's the code anyway for what it's worth -

eval($('#horribleLink').attr('href').replace('javascript:',''));
ipr101
  • 24,096
  • 8
  • 59
  • 61
  • Thanks - this is what I'd resorted to before I asked the question (I should probably have mentioned). I'm hoping someone knows the *why*, too. – Ben Hull Aug 03 '11 at 13:50
0

Use the native Javascript click method and you've got yourself a working click!

$('button.linkProxy').click(function(){
    $('#' + $(this).attr('rel')).click()[0].click();
});

I kept the jQuery click assuming that Javascript click will bypass jQuery triggers in which case you'll want to keep both. Otherwise, if I'm wrong (or you don't need to account for trigger) you can reduce it to:

$('button.linkProxy').click(function(){
    $('#' + $(this).attr('rel'))[0].click();
});
Nathan J.B.
  • 10,215
  • 3
  • 33
  • 41
-1

If I understand correctly the question, the issue is that you have something like this:

 <a href="javascript:alert('hello');" onclick="javascript:alert('clicked');">Test</a>

And you claim that when the javascript is on the href, the onclick event is not fired. Correct? If so, what I am seeing is that both get fired, first onclick and then the javascript inside href.

Icarus
  • 63,293
  • 14
  • 100
  • 115
  • This is not the problem at all. The problem is he's trying to trigger the `href` action from another JavaScript function. – gen_Eric Aug 03 '11 at 13:47
  • No - the links I'm working with have no onclick, only javascript inside the href. It doesn't fire when the click event is triggered programmatically. – Ben Hull Aug 03 '11 at 13:48
  • @Beejamin I see what you mean. – Icarus Aug 03 '11 at 13:50