2

I need to trigger the click event on a link and then, if none of the listeners prevented the default, change the location.

This is what I've got so far:

var $el = $('a#my_special_link');
var onClick = $el.attr('onclick');

// Hack to capture the event object
var ev_reference;
var ev_capture = function(ev) { ev_reference = ev; }
$el.bind('click', ev_capture);

// Don't leave out the onClick handler
if ( typeof onClick == 'function' )
    $el.bind('click', onClick);

$el.trigger('click');

// Clean up
$el.unbind('click', ev_capture);
if ( typeof onClick == 'function' )
    $el.unbind('click', onClick);

// Redirect if necessary
if ( ! ev_reference.isDefaultPrevented() )
  window.location = $el.attr('href');

Any suggestions for improvement are welcome.

PS: Yes, it's just how a regular link would work, except you can do some other processing in between.

PPS: No, just doing $el.trigger('click'); will not change the location.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
scribu
  • 2,958
  • 4
  • 34
  • 44

4 Answers4

4

enter code hereTo extract my notes to others posts: (another way to say same basic stuff)

      <a href="somewhere" id="mylink">MyLink</a> 
        <script>jQuery('#mylink').click(function(){
            // do whatever I want here, then redirect
             window.location.href = "http://stackoverflow.com";
        });
        function doClick(){
            jQuery('#mylink').trigger('click'); 
        };
        // trigger the redirect now
        doClick();
        </script>

EDIT1:@ comments:

If the "other" you describe returns false, you at that point, terminate the callback with the false - so you are correct but has nothing to do with this handler. Which ever one hits first executes, and the other never does return, and this one redirects prior to the other one hitting the log if it executes first.

In order to put your log in, you put that where I have my

 "// do whatever I want here, then redirect"

comment To remove the other event, then bind with this one only:

   <a href="somewhere" id="mylink">MyLink</a> 
        <script>jQuery('#mylink').unbind('click').bind('click', function(){
            // do whatever I want here, then redirect
             window.location.href = "http://stackoverflow.com";
        });
        function doClick(){
            jQuery('#mylink').trigger('click'); 
        };
        // trigger the redirect now
        doClick();
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • That won't work with another handler. For example: jQuery('#mylink').click(function(){ console.log('another handler'); return false; }); – scribu Nov 23 '09 at 23:58
  • The problem is that I don't have control over the other handlers. I just have to make sure they are executed and then decide if I should redirect or not. – scribu Nov 24 '09 at 01:05
  • The unbind can get you control before the other takes place, but of course if a link executes to another site, you will NOT have the choice as the train will have left the station and the page will be replaced. – Mark Schultheiss Nov 24 '09 at 14:15
1

http://docs.jquery.com/Events/trigger#eventdata

$('a#my_special_link').trigger("click");
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
0

"if none of the listeners prevented the default, change the location."

Sounds exactly how a normal link behaves...?

Anyway, if you are trying to look for "return false", it will not be found using isDefaultPrevented(), which only will return true if preventDefault() is called from the same event object. In this example, I'm sending the event object to whatever() and if that function sets preventDefault(), the window will relocate anyway (is that what you need...?)

$('a#my_special_link').bind('click', function(e) {
  whatever(e);
  if (e.isDefaultPrevented()) {
    window.location = $(e.target).attr('href');
  }
});
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • Any handler - except onClick="" - that either returns false or calls ev.preventDefault() will cause isDefaultPrevented() to return true, so that's not an issue. The problem is that I'm not the one writing the onClick="" attribute. I just have to handle it. – scribu Nov 23 '09 at 22:55
  • OK, so how do you want to handle it? it sounds like you can simply trigger the click using trigger('click'), and then let the browser redirect naturally if no eventHandler prevented the default. – David Hellsing Nov 23 '09 at 23:01
  • For security reasons, I presume, the browser will _not_ redirect if you simply trigger the click event. – scribu Nov 23 '09 at 23:09
  • trigger the the click, if you are on the SAME page (*or same site) will redirect to the default if that is what the link does you trigger the click on - just like having a link to another site and manually clicking it. – Mark Schultheiss Nov 23 '09 at 23:15
  • Try this: link and see what happens. (Hint: nothing) – scribu Nov 23 '09 at 23:20
  • Yours adds the EVENT HANDLER (DO THIS WHEN I CLICK) not the event TRIGGER (DO the event now) make it MyLink – Mark Schultheiss Nov 23 '09 at 23:28
  • NOTE: my "somewhere" should be a valid http ref to somewhere you want to go like http://stackoverflow.com/questions/1786377/jquery-simulate-native-click – Mark Schultheiss Nov 23 '09 at 23:31
  • .click() - with no arguments - is shorthand for .trigger('click'). Try it both ways, if you're not convinced. – scribu Nov 23 '09 at 23:47
0

If I understand your question correctly, you have an a element that you don't control, which has an onclick attribute that returns false. Returning false from an onclick handler prevents a click on the link from taking you to the linked page. And you don't want that.

You could store the onclick handler function and then remove it from the link element:

var $a = $('#my_special_link'); 
var onclickHandler = $a.attr('onclick');
$a.removeAttr('onclick');

Then cal the stored handler function in your custom click handler:

$a.click(function() {
    // ...
    onclickHandler();
    // ...
});
mtyaka
  • 8,670
  • 1
  • 38
  • 40
  • Yes, I'm already doing that with $el.bind('click', onClick); Don't know if I should remove the onclick attribute, though. – scribu Nov 23 '09 at 23:37