Reputation: 9806
I'm designing a web site and I would like to be able to call a function 1 second after the last user input. I tried using onKeyUp, but it waited 1 second after the first keystroke.
Does anyone know how would this be possible?
Upvotes: 25
Views: 29055
Reputation: 138
Here is a spun off version based off of @madx. Included features are add remove listener, key string reading within one second, clearing the key string, comparing the key string with a result string.
const onKeyHandler = function (e) {
// Init a timeout variable to be used below
let timeout = null;
// Clear the timeout if it has already been set.
// This will prevent the previous task from executing
// if it has been less than <MILLISECONDS>
clearTimeout(timeout);
// Make a new timeout set to go off in 1000ms (1 second)
timeout = setTimeout(function () {
// console.log('Pressed so far:', key.join());
input.push(e.key)
console.log(input.join(''))
if (input.join('') == "ResultString") {
//remove listener
window.removeEventListener('keyup', onKeyHandler);
clearInterval();
} else {
}
_.debounce(() => {
input = [];
clearInterval();
},1000)()
}, 1000);
};
window.addEventListener('keyup', onKeyHandler);
Upvotes: 0
Reputation: 7203
// Get the input box
let input = document.getElementById('my-input');
// Init a timeout variable to be used below
let timeout = null;
// Listen for keystroke events
input.addEventListener('keyup', function (e) {
// Clear the timeout if it has already been set.
// This will prevent the previous task from executing
// if it has been less than <MILLISECONDS>
clearTimeout(timeout);
// Make a new timeout set to go off in 1000ms (1 second)
timeout = setTimeout(function () {
console.log('Input Value:', input.value);
}, 1000);
});
<!-- a simple input box -->
<input type="text" id="my-input" />
Credits to: Wait for User to Stop Typing, in JavaScript
Upvotes: 2
Reputation: 13194
There is some simple plugin I've made that does exacly that. It requires much less code than some proposed solutions and it's very light (~0,6kb)
First you create Bid
object than can be bumped
anytime. Every bump will delay firing Bid callback for next given ammount of time.
var searchBid = new Bid(function(inputValue){
//your action when user will stop writing for 200ms.
yourSpecialAction(inputValue);
}, 200); //we set delay time of every bump to 200ms
When Bid
object is ready, we need to bump
it somehow. Let's attach bumping to keyup
event
.
$("input").keyup(function(){
searchBid.bump( $(this).val() ); //parameters passed to bump will be accessable in Bid callback
});
What happens here is:
Everytime user presses key, bid is 'delayed' (bumped) for next 200ms. If 200ms will pass without beeing 'bumped' again, callback will be fired.
Also, you've got 2 additional functions for stopping bid (if user pressed esc or clicked outside input for example) and for finishing and firing callback immediately (for example when user press enter key):
searchBid.stop();
searchBid.finish(valueToPass);
Upvotes: 0
Reputation: 21
Just modify your html input and toss that first line into your existing functions so you're not having to recode anything you have. It will not affect any old code-calling functions either, since if onkeypress
is not set then mykeypress
will always be < 1.
var mykeypress=0;
var mysleep=1000; //set this higher if your users are slow typers
function mytest(id,text) {
mykeypress--; if(mykeypress > 0) { return; }
//anything you want when user stops typing here
alert("Keypress count at "+mykeypress+" ready to continue
id is "+id+" arguement is "+text);
}
input type="text" name="blah" id="55" onkeypress="mykeypress++"
onkeyup="myid=this.id;setTimeout(function (){mytest(myid,'a test')},mysleep)"
REVERT to old way seamlessly:
input type="text" name="blah" id="55" onkeyup="mytest(this.id,'a test')"
Upvotes: 0
Reputation: 9806
Nevermind, I found a way to do it. I call a function on each onkeyup() which increment a counter and then wait 1 second. After the 1 second elapsed, it decrement the counter and check if it's equal to 0.
var keystrokes = 0;
function askAgain()
{
++keystrokes;
setTimeout(reveal, 1000);
}
function reveal()
{
--keystrokes;
if (keystrokes == 0)
alert("Watch out, there is a snake!");
}
Upvotes: 1
Reputation: 827366
Another similar approach, without globals:
var typewatch = function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
}
}();
...
<input type="text" onKeyUp="typewatch(function(){alert('Time elapsed!');}, 1000 );" />
You can this snippet here.
Upvotes: 47
Reputation: 11230
You can use a keyDown
(or keyUp
) event that sets a function to run in 1 second and if the user types another key within that second, you can clear the timeout and set a new one.
E.g.
var t;
function keyDown()
{
if ( t )
{
clearTimeout( t );
t = setTimeout( myCallback, 1000 );
}
else
{
t = setTimeout( myCallback, 1000 );
}
}
function myCallback()
{
alert("It's been 1 second since you typed something");
}
Upvotes: 20