3

I'm making a site where a user repeatedly clicks a button to increase his/her score. In order to prevent people cheating, I want to measure the amount of time between each click, and if they are clicking inhumanly fast and there is very little time between clicks, I want a CAPTCHA or something to come up.

How would I measure the time between clicks?

Smi
  • 13,850
  • 9
  • 56
  • 64
Taimur
  • 3,171
  • 8
  • 32
  • 38

2 Answers2

4

The click handler can just maintain a timestamp as a JavaScript "Date" instance. Subtract two of those and you have the interval in milliseconds.

Be aware that the clock accuracy is not necessarily that great, and that humans can generate clicks pretty darn fast. Windows, I think, won't give you much better than 15 milliseconds granularity.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • I think grabbing the timestamp from a Date object doesn't suffer from a granularity problem. `setTimeout` or `setInterval` suffer from this problem. Or am I wrong? – meouw Mar 05 '11 at 13:36
  • Well you may be right, but keep in mind that the event dispatch mechanism itself may play a role. To put it another way, there's a big difference between the way a low-level device interrupt triggers a response in a game console from the way a web browser relays a mouse click to a JavaScript handler. There are a few more thick layers of software involved, none of which are particularly well-designed for real-time game play. – Pointy Mar 05 '11 at 13:39
  • Thanks for the reply, what do you mean by granularity? – Taimur Mar 05 '11 at 13:55
  • Well for some things, the accuracy of the clock is pretty low, and you can't trust it for time intervals less than about 15ms. As @meouw says, it may be that things are better when handling events, but you should do some tests and see how it behaves. – Pointy Mar 05 '11 at 13:57
3

My suggestion would look like:

$('button').click((function() {
    var history = [],
        last    = +new Date();

    return function(e) {
        history.push(e.timeStamp - last);

        console.log(history[history.length - 1]);
        last = e.timeStamp;
    };
}()));

This will output & store the difference between two clicks in miliseconds. You could use the history array to get an average value and check if that is below 50ms or something.

Demo: http://jsfiddle.net/TxKjT/

Demo with average check: http://jsfiddle.net/TxKjT/2/

jAndy
  • 231,737
  • 57
  • 305
  • 359
  • That's exactly the kind of thing I was looking for, thanks! This may sound a bit stupid, but how do I view the console log which the data is stored in? thanks – Taimur Mar 05 '11 at 13:57
  • @Taimur: you need a debugger/tool which understands the output, Like *Firebug* or *Webkits Developer tools* – jAndy Mar 05 '11 at 14:00
  • @Taimur: Howeever, I updated the second example for the output. – jAndy Mar 05 '11 at 14:03
  • oh yeah, that's very useful would I be able to, instead of making text appear, run a CAPTCHA or something? – Taimur Mar 05 '11 at 14:04
  • @Taimur: of course you are! But don't forget, we're just in a browser Javascript environment. So this can get manipulated and you shouldn't trust in it too much. – jAndy Mar 05 '11 at 14:08
  • in what way can a user manipulate it? I understand that it's next to impossible to stop cheats, but I'd like to narrow it down as much as possible and then hand pick the remaining few out. – Taimur Mar 05 '11 at 14:10