Skip to content

How Not to Bind Click Events to Hyperlinks

With the prevalence of jQuery tutorials and JavaScript advice in general, it's common to see JavaScript events bound to the click event.

Without jQuery this is done with:

document.querySelector(selector).addEventListener(
  "click",
  function (e) {
    // ...code here...
  },
  false
);

(for purposes of this example, we'll assume that there's only one element in the selection)

With jQuery this is done with

$(selector).click(function (e) {
  // ...code here...
});

…or…

$(selector).on("click", function (e) {
  // ...code here...
});

Seeing this code, you could be forgiven for thinking that ...code here... is where you start writing your functionality when adding a click handler to a hyperlink.

Simple AJAX examples often appear as:

$("a").click(function (e) {
  $.get(this.href).then(doStuffWithResults);
  e.preventDefault();
});

That code is terrible. Don't ever use it.

The problem with that code is it completely ignores what is doing the clicking.

You see, when a link is clicked, the user has the option of telling the browser how they want to navigate with that link. The majority of the time the user will simply left click, because the user wants to navigate directly to that link.

But occasionally users do things differently. Users might middle-click or Ctrl + click a link to open it in a new tab. They might Shift + click the link to open it in a new window.

In those cases, the click handler will do the wrong thing.

Doing the right thing

Doing the right thing is trivial. The click handler should only kick in when:

  • the left mouse button is clicked
  • the ctrl key is not down
  • the alt key is not down
  • the shift key is not down

In jQuery it's as simple as:

$("a").click(function (e) {
  if (e.which === 1 && !e.ctrlKey && !e.altKey && !e.shiftKey) {
    // ...code here...
    e.preventDefault();
  }
});

A few simple checks in an if statement, and your power users no longer hate your guts!

The vanilla JS version of this is just as simple:

document.querySelector("a").addEventListener(
  "click",
  function (e) {
    if (e.button === 0 && !e.ctrlKey && !e.altKey && !e.shiftKey) {
      // ...code here...
      e.preventDefault();
    }
  },
  false
);