Hello there,

I'm running into a minor problem. I want to execute an onKeyUp action after a short delay when a key is released. So for example when the user gets his finger off the "y" button, I want to execute an action related to that "Y" after 1 second.

BUT: I want to execute it only once. With the script I now have, 10 timers start running when the user types in 10 letters, which means 10 actions are executed, each after 1 second after releasing a key, while I only want to execute 1 action.

So when the user types in "hello", an action is executed for each letter he typed in. What I want is the timer to reset after he types a new letter within a second after he types a letter. So when he types "hello" within like a second, only one action is executed. This script:

setTimeout(function(){

actions..

}, 1000);

Keeps resetting the timer over and over. Any suggestions?

Recommended Answers

All 19 Replies

You need to first cancel the timeout (google that).

I already did, and I found some tutorials on the timer functions, but none of them explains how to execute such an action only once: I don't know how to reset the timer. They do explain it, but only for JQuery, and I'm not using JQuery at the moment. Is there any way to do it without JQuery? Cause I don't know where to place the clearTimeout() function, and it also does not seem to reset the timer, only to pause it.

it also does not seem to reset the timer, only to pause it.

False.

Cause I don't know where to place the clearTimeout() function

That needs a bit of logic thinking: what exactly is the moment your script should figure that the timeout it set should not be called after all?

Member Avatar for stbuchok

I would assume something like this should do it.

var timer = 0;

$('textboxid').keydown(function(){
   clearTimeout(timer);
});

$('textboxid').keyup(function(){
   timer = setTimeout(function(){
      //do what you need to in 1 second
   }, 1000);
});

settimeout its basicaly the only thing you need for this

you need to do something of this sort:

var timer = setTimeout(
     function(){
             ...actions...;
             clearTimeout(timer)},1000);

No, definetely not. Clearing a timeout just before it's actually finished makes no sense.

No, definetely not. Clearing a timeout just before it's actually finished makes no sense.

:')
That's how you read it, but it is the other way around! You've read it wrong and of course saying "no and definitely not" without a trial, is also wrong.

Okay, well, tell me what's wrong with how I read it:
- You set a timer.
- In 1 second, it fires.
- The anonymous function is called:
- Actions are being done :)
- The timeout is cleared. This makes no sense because it's already fired.

That's the whole point, or is it?
Are you trying to actually convince me that you don't have a clue about timed scripts programming(!?!) -cause you're almost there.

Let's than make it a completely incomprehensible (a one liner - my favorite) - but yet again, a perfectly working example you never saw before.
A delayed function that runs (as requested) only once:

;setTimeout(function(){alert('R U Late?')},1000);

Any other comments?!...

Yes. You don't understand the entire thread nor do you understand my comments on your previous piece of code. The setTimeout needs to be cleared for the problem to be solved, and in your first piece of code you did that on the wrong place and now you don't do it at all (and it's not that incomprehensible as you may find it). What you need is something like stbuchok already posted, for example:

if(timeout) clearTimeout(timeout);
var timeout = setTimeout(function() {
  // actions..
}, 1000);

Yes. You don't understand the entire thread nor do you understand my comments on your previous piece of code. The setTimeout needs to be cleared for the problem to be solved, and in your first piece of code you did that on the wrong place and now you don't do it at all (and it's not that incomprehensible as you may find it). What you need is something like stbuchok already posted, for example:

if(timeout) clearTimeout(timeout);
var timeout = setTimeout(function() {
  // actions..
}, 1000);

You are right, of course, -but the title says:
Execute action after x seconds only once

Whereas: ;setTimeout(function(){alert('1 second passed')},1000); does exactly that.
(no need to delete an anonymous function because as soon as it has fired, it is gone - went garbage collected - never to come back again.)
That's what he asked and that's what it does.

But if the task is something else - it is again - not only your fault - but mine too!
:')
If the guy wants to cancel the timed function any time the user has caused another keyup event, yet register the last one.
Well than, it's not that simple as it looks...

Here fore I offer this solution:

function timeShift(){
		clearTimeout(timeShift);
		timeShift=setTimeout("yourFunction()",1000);
		}

executes only after the client has stopped typing.
Call

yourElement.onkeyup=timeShift

Define yourFunction() anywhere. (complex functions get ugly when put inside the timer).

Regards @all.

Yes, correct. Only thing is, as far as I can remember this will trigger an error on the first keydown as the timeout has not yet been set.

Nope!
This is the only working solution offered here so far - and it not only works perfectly and rock solid reliable but it is the shortest and the cutest one you may ever see.

Otherwise, the code you proposed does exactly what this guy has problems with.
It fires only once - but when it fires - it fires them all.

My function does exactly what he asked for, executes only once and only after the last stroke.


Regards

Otherwise, the code you proposed does exactly what this guy has problems with.
It fires only once - but when it fires - it fires them all.

False, have you tested it?

But of course I have - have you?

As I already mentioned: "saying 'no and definitely not' without a trial, is close to being wrong."

My trial revealed that it accumulates all events captured during the specified time (creating an independent timer for every key stroke) than fires them all in one sequence while accumulating new ones. That's exactly what was bothering our guy minitauros and the reason why he posted this question. He also got stuck at the same point himself.

At first glance, this may seem like a silly simple problem to solve; but, it just aint that simple! - Some of the best coders to date may heavily sweat over it and perhaps not even solve it - at least not without some heavy stunts and edgy acrobatics of multi forked functions. Or three separate functions trying to keep the state of things and passing from one to another.

In fact, there is a complete library namely Rx.js which deals with this and similar problems, but they are licencing it...commercially I think, or perhaps they already did.

Nice talking to you.
Regards

It depends a bit on how you implement it. You'll have to make sure that the var you're referring to is the same one everywhere. Anyhow, have a nice day.

You are wellcome, nice day 2U2.

How about enabling the timer to false?

Timer2.Enabled = false;

protected void Timer2_Tick(object sender, EventArgs e)
        {
            //Do Action Then
            Timer2.Enabled = false;
        }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.