When somebody clicks my checkboxes, from a long list of checkboxes, I want to show the number of selected checkboxes in a little popup element. My problem is, the little popup element should disappear 5 seconds after the last click, which is OK for one checkbox being clicked, but if I quickly check 5 boxes, the timer is still set on the first box, resulting in the popup element disappearing too quickly.
As you can see in my function, I've tried using the clearTimeout(timeoutName) function but have experienced some troubles applying it. The console log states that the clearTimeout(timeoutName) is undefined, which I can understand: the setTimeout hasn't even started yet.
How can I check that the timer exists before I clear it? Or is this really not the best method? When a checkbox is checked (this function runs) there could be a timer running but sometimes there could not be.
$('.name_boxes').live('click', function() {
var checked_count = $('.name_boxes:checked').length;
// other stuff
clearTimeout(hide_checked_count_timer); // if exists????????
$(".checked_count").hide();
$(".checked_count").text(checked_count+" names selected");
$(".checked_count").show();
hide_checked_count_timer = setTimeout(function() {
$(".checked_count").hide();
},5000);
});
Any help gratefully received...
Just declare the timer variable outside the click handler:
var hide_checked_count_timer;
$('.name_boxes').live('click', function() {
var checked_count = $('.name_boxes:checked').length;
// other stuff
clearTimeout(hide_checked_count_timer); // if exists????????
$(".checked_count").hide();
$(".checked_count").text(checked_count+" names selected");
$(".checked_count").show();
hide_checked_count_timer = setTimeout(function() {
$(".checked_count").hide();
},5000);
});
http://jsfiddle.net/kkhRE/
Considering .live has been deprecated, you should be delegating the event with .on instead:
// Bind to an ancestor. Here I'm using document because it an
// ancestor of everything, but a more specific ancestor
// would be preferred.
$(document).on('click', '.name_boxes', function() {
// ...
});
Q. The console log states that the clearTimeout(timeoutName) is undefined, which I can understand: the setTimeout hasn't even started yet.
A. The clearTimeout() function's return value is undefined regardless of whether there was a timeout to be cleared. It doesn't have a concept of "success" that can be tested. If there is a queued timeout associated with the id you pass then it will be cleared, otherwise nothing happens.
Q. How can I check that the timer exists before I clear it?
You can't, at least not in the sense of there being some registry of outstanding timeouts that you can query. As you already know, the .setTimeout() function returns an id for the timeout just queued, and you can use that id to clear it before it runs, but there is no way to test whether it has already been run. The id is just a number so the variable that you saved it in will continue to hold that number even after the timeout has either run or been cleared.
It does no harm at all to call clearTimeout() with an id for a timeout that already ran - basically if the timeout for that id is in the queue it will be cleared otherwise nothing will happen.
The easiest way to test "Is there an outstanding timeout that hasn't run yet" is to set the variable holding the timerid to null when the timeout runs, i.e., within the function you queued:
var timerid = setTimout(function() {
timerid = null;
// other operations here as needed
}, 5000);
// in some other code somewhere
if (timerid != null) {
// timer hasn't run yet
} else {
// timer has run
}
The variable you save the timerid in needs to be in a scope that can be accessed both where you set it and where you test it, i.e., don't declare it as a local variable within an event handler.
You can use the power of short-circuit operators
hide_checked_count_timer && clearTimeout(hide_checked_count_timer);
The right-hand statement will only run if the left-hand variable is not undefined.
to check if it exists use;
if (typeof timerid == 'undefined')
{
//timer has not been set so create it
timerid = setTimeout(function(){ var something = true;}, 5000);
}
Related
I have an automatic mouse with a time interval when I go inside a web. But I have a button that increase that speed but of course when I refresh the page or I go to other part of the web the speed is the first one. I tried with a cookie but I don't know how to do it because by default cookies or localstorage works only with names...
// Default speed
$(document).ready(function() {
t = setInterval(clickbutton, 3000);
}
// Button
function aumentar() {
clearTimeout(t);
t = setInterval(clickbutton, 100);
}
I will be really grateful for your help because I'm going crazy.
Thanks a lot!
The setTimeout() method calls a function or evaluates an expression after a specified number of milliseconds.
The function is only executed once. If you need to repeat execution, use the setInterval() method.
Use the clearTimeout() method to prevent the function from running.
The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds).
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
HTML local storage; better than cookies.
Create a localStorage name/value pair with localStorage.setItem("name", "value")
Retrieve the value of "name" and insert it into the element with localStorage.getItem("name")
remove item localStorage.removeItem("name")
var t;
function speed(_speed, boo){
if(boo){
return localStorage.getItem("speed") || 3000;
} else {
localStorage.setItem("speed", _speed);
}
}
$(document).ready(function() {
t = setInterval(clickbutton, speed(true));
// Button
function aumentar() {
clearInterval(t);
speed(100);
t = setInterval(clickbutton, 100);
}
});
I have a probably really simple question but did not find anything about this or maybe did not find the right words for my problem.
If have a function to be executed on keypress which also changes my variable A - fine, and it works.
But now I want to give an alternative value to my variable A if the keypress event is not happening.
So I'm looking for the correct command for the naive logic of
if ("keypress event happens") {
A = 1
} else {
A = 2
}
Is there any way to do that in js or jquery with simple true/false checks for the key event?
I've been trying and trying and it did not work once.
Usually, the way one solves this problem is with a setTimeout(). You set the timer for N seconds. If the keypress happens, you cancel the timer. If the keypress doesn't happen, the timer will fire giving you your alternate event.
You probably wrap this in some sort of function that you can trigger whenever you want, but you didn't share the overall context so this is just the general idea:
$("#myObj").keypress(function(e) {
if (timer) {
clearTimeout(timer);
}
// process key
});
var timer = setTimeout(function() {
timer = null;
// key didn't happen within the alltoted time so fire the alternate behavior
}, 5000);
I have a number of different form elements. When any of the form elements have their value changed, I need to make an ajax call 500ms after the change.
However, should another form element have its value changed then I would like to reset the timer to 500ms, thus avoiding multiple Ajax requests for a series of changes that happen within 500ms of each other.
Is there a JavaScript or jQuery solution to this requirement?
Here's some code that demonstrates the principles you're looking for:
// Keeps track of the timer id in a scope that is outside of the event function
// The variable will remain in memory and available to the next event call
var myTimer;
// Detect changes on keyup.
$('.textbox').on('keyup', function () {
console.log('keyup');
setMyTimer(500);
});
// Detect on change.
$('select').on('change', function () {
console.log('change');
setMyTimer(1000);
});
function setMyTimer(timerDelay) {
// if myTimer has a value, then we should clear the timer. This stops us
// from queuing multiple timers
if (myTimer) {
console.log('clear tiemout');
clearTimeout(myTimer);
}
// Set the timer. It will be cleared if there is another handled 'keyup'
// event sooner than the timerDelay parameter
myTimer = setTimeout(function () {
console.log('Ajax stuff');
// ajax stuff
}, timerDelay);
};
Remove the console.log code before using in production.
See this working demonstration:
http://jsfiddle.net/cC6Dq/5/
I was just wondering if there is any risk when you execute code like this:
window.doSomething = function() {
window.doSomething = null;
// do some stuff here
}
Will this always run fine, or might there be a situation in which the garbage collector will clean it up while it's still running?
window.doSomething = null ;
That will just remove the property doSomething from window which was previously referencing your function.
The function that you're currently in will run until the end, because entering the function increases the reference count, preventing it from being destroyed prematurely.
After the function is done, it will be scheduled for garbage collection.
I want to run some code on all my treeView nodes depending on a value returned from the database and repeat this until a certain value is returned.
I was thinking that:
Give all my tree nodes the same css class so I can access them from JQuery
have a timer in my JQuery function that used ajax to go to the database, when a certain value is returned then stop the timer
Two questions here. How can I make my function run for each of the nodes and how do I do a timer in JavaScript, so:
$(function(){
$('cssClassOfAllMyNodes').WhatFunctionToCallHere?((){
//How do I do Timer functionality in JavaScript?
ForEachTimeInterval
{
//use Ajax to go to database and retrieve a value
AjaxCallBackFunction(result)
{
if (result = 1)
//How to stop the timer here?
}
}
});
});
Hope i'm clear. Thanks a lot
thanks a lot for the answer. And i would like you to comment on the design.
Bascially what i'm trying to acheive is a Windows Wokflow type functionality where each node in my tree updates its image depending on its status, where its status is got from querying the database with a key unique to the tree node. I'm open to ideas on other ways to implement this if you have any. thanks again
Without commenting on your design you can refer to these
$.each()
setTimeout() or setInterval()
You can do:
$(function(){
$('cssClassOfAllMyNodes').each(function (){
// Do something with "this" - "this" refers to current node.
});
});
Te proper way to handle timers in JS is to have a reference to each timeout or interval and then clearing them out.
The difference between them is:
The timeout will only run once, unless stopped before;
The interval will run indefinitely, until stopped.
So you can do something like:
var delay = 2000; // miliseconds
var timer = setTimeout("functionToBeCalled", delay);
clearTimeout(timer); // whenever you need.
Please note you can pass a string to setTimeout (same with setInterval) with the name of the function to be called. Or you could pass a reference to the function itself:
var callback = function () { alert(1); };
var timer = setTimeout(callback, delay);
Be sure not to set an Interval for AJAX requests, because you response might be delayed and successive calls to the server could eventually overlap.
Instead, you should call setTimeout and when the answer arrives then call setTimeout again.