Quantcast
Channel: I does Javascript! » Useful Functions
Viewing all articles
Browse latest Browse all 10

Programmatically clicking a link in Javascript

$
0
0

More accurately, this would be called actuating a link (i.e. the process of setting the link's behavior into motion, if you will.) In other words, you have a link:

<a id = 'bingLink' href = "http://www.bing.com">Bing</a>

And you want to programmatically make that link do its thing. This usually means having the browser navigate to the URL specified link's href attribute (though, it can also mean executing some click handler if one happens to be specified on said link.)

To be honest, I don't think there are a ton of real-world uses for this, but there are a few. And depending on your needs, it may not be trivial to accomplish this in a cross-browser fashion. For example:

var myLink = document.getElementById('myLink');
myLink.click();

The above will do the trick in IE, because IE supports .click() on links. Most other browsers don't though, so that's not an all-encompassing solution.

One (partial) solution in non-IE browsers might be to read the href attribute from a given link and then use Javascript to make the browser navigate to to the URL specified by href that way:

function actuateLink(link)
{
     window.location.href = link.href;
}

This is not a complete solution for a couple of reasons:

  1. Navigating by setting window.location.href blows away the document.referrer property.
  2. Any click event handler wired to the link will not execute.

For anyone who has read my post about Re-routing events in Javascript post, you'll know that it is possible to simulate an event though the use of .dispatchEvent(..).

Here's a brief refresher of the part most relevant to this discussion:

var myEvt = document.createEvent('MouseEvents');
myEvt.initEvent(
   'click'      // event type
   ,true      // can bubble?
   ,true      // cancelable?
);
document.getElementById('myLink').dispatchEvent(myEvt);

This approach will ensure that any click event handlers will fire as desired (though, it's worth nothing that you'd have to handle mousedown, mouseup, keydown, keypress etc... separately,) but it does NOT actuate the link!

This might surprise you. Dispatching a click event to a link doesn't actually cause the browser to navigate to the URL specified by that link's href property. This actually isn't shocking to me, personally. A little surprising, but not shocking.

Anyway, one option is to dispatch the click event and then use window.location.href. This should achieve (some of) the desired effect, but again, the document.referrer will not be preserved if you do this. Also, if the event handler prevents the default action, this method will not honor the code that prevents the default action (i.e. the link will navigate despite the code that attempts to prevent it from doing so.)

You can work around the window.location.href problem by creating a <form> element, settings its action attribute to that of the link's href attribute and then submitting the form through myForm.submit(), but the problem regarding preventing the default action remains.

A 95% Solution

Is there a 100% perfect solution to this problem? Probably, but I'm not 100% perfect. I'm only 95% perfect, so I give you my 95% solution:

function actuateLink(link)
{
   var allowDefaultAction = true;
      
   if (link.click)
   {
      link.click();
      return;
   }
   else if (document.createEvent)
   {
      var e = document.createEvent('MouseEvents');
      e.initEvent(
         'click'     // event type
         ,true      // can bubble?
         ,true      // cancelable?
      );
      allowDefaultAction = link.dispatchEvent(e);           
   }
         
   if (allowDefaultAction)       
   {
      var f = document.createElement('form');
      f.action = link.href;
      document.body.appendChild(f);
      f.submit();
   }
}

To use it:

actuateLink(document.getElementById('bingLink'));

This code is self explanatory, right?

If .click() is available, let's use that. If not, let's try to do a W3C-style create and dispatch event. Then, in order to maintain the document.referrer property, we'll use a form submission, but we only want to submit that form if the event handler (if there is one) for the click event doesn't explicitly prevent the default action.

This isn't a 100% perfect solution because, actuating a link in this manner is only going to invoke click handlers and navigate to the URL of the link's href attribute (if appropriate to do so.) It isn't going to invoke handlers for any other types of events. And I'm not about to create and dispatch every possible kind of event. Besides, I think we can all agree that click is by far the most common scenario.

So there ya go. Programmatically clicking (or more accurately, actuating) a link with Javascript. Enjoy!

(Tested: Firefox 3.5.7, IE8, Opera 10.01, Safari/Win 4.0.3, Chrome 3)


Viewing all articles
Browse latest Browse all 10

Trending Articles