Recently I wanted to improve they way some anchors where handled in my recent project, it works a bit like adding and removing items to/from a list. But it was possible to trick the interface by quickly clicking multiple times on a link before the AJAX request was finished, while the back-end handled this without any problems, the interface for the visitor couldn't. And since I'm a neat freak and I had a few minutes to spare, I came up with the following.
A working example: http://dynom.nl/jquery/clickmanycallonce.html.
My.items = {
init : function () {
// Bind the real item only once, and the dummy item permanently
// This way the *real* item is only called once, regardless of the amount of clicks
// And the link remains clickable but doesn't trigger the browser to follow it.
$('ul>li>a.item').one('click', My.items.real_action).bind('click', My.items.dummy_action);
},
dummy_action : function () {
$(this).html( $(this).html() + '.' );
return false;
},
real_action : function () {
/* Fancy AJAX call, that shouldn't be executed more then once for every click */
$('div#frame').html($('div#frame').html() + "<br>\nCalling 'real_action' for anchor: " + $(this).html());
return false;
}
};
// When the DOM is ready
$(document).ready(function () {
// Attach the filter to our input and list
My.items.init();
});
While the code is fairly self explanatory and quite simple here the steps in a bit more detail:
- Unobtrusively binding, as soon as the DOM is ready.
- Binding the real action handler on 'click' action with jQuery's 'one()' event handler
- Binding the dummy action handler on 'click' action with the 'bind()' event handler
This situation is probably only favorable if the item you click is removed from the DOM (or has actions re-bound after the call) else it might not be what you want.