I'm currently working on a project that's heavily JavaScript driven. One of the key goals of the project is to get the user to click a bright yellow button (I won't go in to any more detail than that).

The button is perfect, it's eye catching and when you see it, you just want to click on it. When it's clicked, it fires the appropriate JavaScript event.

UK EVENTAttend ffconf.org 2024

The conference for people who are passionate about the web. 8 amazing speakers with real human interaction and content you can't just read in a blog post or watch on a tiktok!

Problem!

However, our success was also our downfall: the button would be clickable before the DOM had completely loaded.

The application wasn't designed to degrade, mostly because it has a particular targeted audience, so the clicking action screws up the experience if the DOM isn't finished and all the appropriate click handlers are in place (and yes: I did argue for a degrading system, but that's entirely another story).

Solution.

The solution is straight forward. You hook a click caching system during the DOM load.

All the links you want to catch an early click event, you add the following:

<a href="#?" 
  onclick="return earlyClickHandler.call(this);"
>CLICK ME!</a>

Then the following JavaScript needs to be added as the first block of JavaScript directly after you load jQuery (or your library du jour), in the <head> tag:

function earlyClickHandler() {
  var t = this;
  if (typeof $.isReady == 'boolean' && $.isReady) {
    return true;
  } else if (!t.clicked){
    t.clicked = true;
    // once DOM is loaded, fire this click handler
    $(function () { 
      $(t).click();  
    });
  }
  return false;
}

The effect is the user can click on the link and it won't do anything until the DOM is loaded, and once it is loaded, it will fire the click event the user requested.

This example only caches one click event per link (with the t.clicked = true). It is also using jQuery to test if the DOM is ready, and if it is, just pass control back to the DOM, which is in turn passed back to jQuery (assuming you've hooked an event).

It should be simple enough to convert the function to work with Prototype or YUI or the library (or not) of your choice.

Wrap up.

I would only recommend using this technique when you absolutely must, because by adding the onclick attribute, you're mixing behaviour with presentation. There are articles explaining why this is a best practise but I believe, in the right situation, it can benefit the user.