Reputation: 73908
I need to detect when a user keep press a button for X second and call function in JavaScript. Could you point me out in right direction?
Upvotes: 5
Views: 12736
Reputation: 18233
You can accomplish this simply by recording the time at which a key is pressed, and then checking the time again when the key is released. Construct a JS object which maps key-codes to dates.
On keyDown, record the key and current time (if it's not already set—some keys trigger multiple keydowns while being held). On keyUp, find the time difference, clear the map entry, and then process accordingly:
$(function () {
var keyTimes = {};
$(document).keydown(function (e) {
if (!keyTimes["key" + e.which]) {
keyTimes["key" + e.which] = new Date().getTime();
}
});
$(document).keyup(function (e) {
if (keyTimes["key" + e.which]) {
var x = new Date().getTime() - keyTimes["key" + e.which];
delete keyTimes["key" + e.which];
// key was held for x/1000.0 seconds
}
});
});
Upvotes: 1
Reputation: 6442
Watch for keydown
and keyup
events. jQuery's keydown
event triggers recursively based on the user's keyboard settings for press and hold of keys. You can alternatively set your own recursive checking timeout if you would like to check this more/less frequently or abstract your checking away from varying user's keyboard settings.
This code (thanks to nbrooks for the prompting), monitors each key down event as their own instance, and so will allow for multiple keys to be press and held on a keyboard, each with their own triggertimes.
$(function(){
var keyDownArray = {};
var triggerTime = 3000; // number of ms to trigger function at
var keyDownEvent = function(e){
// use the event keyCode as a unique identifier
if(!(e.keyCode in keyDownArray) ){
// use the event keyCode as a unique identifier
// use setTimeout to make sure trigger only occurs once
keyDownArray[e.keyCode] = setTimeout(function(){
// call your function here (can pass in e.keyCode if function requires custom functions on a per key basis)
console.log('triggered for key '+e.keyCode);
}, triggerTime);
}
}
var keyUpEvent = function(e){
// on key release, clearTimeout and delete object key
clearTimeout(keyDownArray[e.keyCode]);
delete keyDownArray[e.keyCode];
};
$(document).on('keydown', keyDownEvent)
.on('keyup', keyUpEvent);
});
PS. it may be worth adding a throttler (something like Ben Almans debounce/throttle plugin) to decrease the potential load of this function
Upvotes: 1
Reputation: 180
Use keydown() and keyup() to check for the keypress. Get the current system time with keydown() and compare that with the current system time when you get the keyup().
var starttime;
var curKey;
$('#seconds-counter').keydown(function(e) {
if (curKey != e.which) {
var d = new Date();
starttime = d.getTime();
$('#down-time').text(starttime);
curKey = e.which;
}
});
$('#seconds-counter').keyup(function() {
var d = new Date();
var endTime = d.getTime();
$('#up-time').text(endTime);
var timeTaken = endTime - starttime;
$('#result-val').text(timeTaken / 1000);
curKey = null;
});
(Edit: forgot the last bit :-) ) Call your function at the end of the keyup(), after curKey = null.
Upvotes: 0
Reputation: 5454
Check out the jquery docs, they're super awesome. Something like this could give you the gist, though.
var keyTO,
seconds = 5;
$( "#i" ).on({
keypress: function(e) {
if(keyTO) {
clearTimeout(keyTO);
keyTO = null;
}
keyTO = setTimeout(someFn, seconds*1000);
},
keyup: function(e) {
clearTimeout(keyTO);
keyTO = null;
}
});
function someFn() {
// only called after full timeout
alert('Sweet.');
}
Upvotes: 1
Reputation: 128791
You can use a setTimeout
function on the keydown
event which will fire after X seconds to compare the time that event was triggered to the last time a keyup
was triggered - if at all.
var lastKeyUpAt = 0;
$(elem).on('keydown', function() {
// Set key down time to the current time
var keyDownAt = new Date();
// Use a timeout with 1000ms (this would be your X variable)
setTimeout(function() {
// Compare key down time with key up time
if (+keyDownAt > +lastKeyUpAt)
// Key has been held down for x seconds
else
// Key has not been held down for x seconds
}, 1000);
});
$(elem).on('keyup', function() {
// Set lastKeyUpAt to hold the time the last key up event was fired
lastKeyUpAt = new Date();
});
elem
here is the element you're wanting to handle the event on.
Upvotes: 8