So, i have this little function:
carousel_controls_buttons.live('click', function(e){
setTimeout(function(){
info_board_span.append(info_board_description);
e.preventDefault();
}, 450);
});
What i'm trying to do is stop appending info_board_description more then one time after two, three fast clicks. When i do this this data appends more than one time and i have content duplication. How can i stop this for some time, f.e. this 450ms? Thx for help.
Use a boolean to control it.
var flag = true;
carousel_controls_buttons.live('click', function(e){
e.preventDefault();
if (flag) {
setTimeout(function(){
info_board_span.append(info_board_description);
flag = true;
}, 450);
flag = false;
}
});
You can use clearTimeout function:
var t = '';
carousel_controls_buttons.live('click', function(e){
clearTimeout(t);
t = setTimeout(function(){
info_board_span.append(info_board_description);
e.preventDefault();
}, 450);
});
example: http://jsfiddle.net/xhSvC/
Note that live method is deprecated, you should use on method instead.
While the other answers ought to work, I would like to introduce you to the concept of debounce & throttle.
http://benalman.com/projects/jquery-throttle-debounce-plugin/ is one plugin you may use to achieve what you need, ie, ensure a function is executed only once per x seconds.
Throttle versus debounce
Both throttling and debouncing will rate-limit execution of a
function, but which is appropriate for a given situation?
Well, to put it simply: while throttling limits the execution of a
function to no more than once every delay milliseconds, debouncing
guarantees that the function will only ever be executed a single time
(given a specified threshhold).
carousel_controls_buttons.live('click', function(e) {
$.debounce(450, function() {
info_board_span.append(info_board_description);
e.preventDefault();
});
});
Put an count over there say var count=0; increment when hit and check for the condition if count==1 append it if not leave it
There is a one event for achieve this:
carousel_controls_buttons.one('click', function() {
setTimeout(function(){
info_board_span.append(info_board_description);
e.preventDefault();
}, 450);
});
Related
Testing this out and I'm trying to figure out how to stop a delay if i click another attribute. I'll post the site address to make this explanation a lot better, but basically when you press menu my nav appears with a delay, when I press Assignment 6 I want everything else to hide, which it does, but I see that because I have a delay when it hides and it's not done delaying it will continue to print out the rest of the elements even though they are supposed to be hidden. Also a disclaimer, I've gotten a lot of heat on this site before because I think people think I expect an answer. This is not the case, I love to learn and although the answer would be helpful and I would be able to de-engineer it and learn it, I would much rather have some guidance. So yeah, I'm not just looking for an answer if anyone thinks that's what I'm on here for (I come on here when I can't figure it out any other way).
site
my jQuery script:
$(document).ready(function () {
//$('ul').hide();
$('ul li').hide();
$('nav>li').hide();
$('nav>h1>').click(function (event) {
event.preventDefault();
$('nav>ul li:hidden').each(function(i) {
$('nav>li').show();
$('nav>h1').hide();
$(this).delay(i*600).fadeIn(200);
});
$('nav>ul li:visible').each(function(i) {
$('nav>h1').hide();
$(this).delay(i*600).fadeOut(200);
});
return false;
}); //closes a.btnDown
$('nav>li').click(function (event) {
$('nav>h1').show();
$('nav>li').hide();
$('ul li').hide();
return false;
}); //closes a.btnDown
}); //closes .ready
setTimeout is a useful mechanism to solve what you are after. It waits for (at least) the delay specified, and executes the callback function.
var elements = $('nav>ul li:hidden');
var timeoutId;
function doAnimation(index) {
timeoutId = window.setTimeout(function () {
if (index < elements.length) {
$(elements[index]).fadeIn(200);
doAnimation(++index);
}
}, 600);
}
The clue is to declare the timeoutId outside a recursive function, and assign it within the function. By doing it in a recursive fashion, you don't start the next timeout before the current timeout is finished, and it can be aborted at any time.
window.clearTimeout(timeoutId);
I've made a little fiddle that demonstrates the concept, but I haven't implemented a complete solution. Hope this helps you get further with your project.
http://jsfiddle.net/pyMpj/
You can replace your delays with setTimeout and clear them with clearTimeout
$('nav>ul li:hidden').each(function(i) {
$('nav>li').show();
$('nav>h1').hide();
var fadeTimeout = setTimeout(function () {
$(this).fadeIn(200);
}, i * 600);
});
$('nav>li').click(function (event) {
$('nav>h1').show();
$('nav>li').hide();
$('ul li').hide();
clearTimeout(fadeTimeout);
return false;
});
So, I want to put delay on this JavaScript code.
$(function(){
$('.clickThis').each(function(){
$(this).click();
});
});
I tried this
$(function(){
$('.clickThis').each(function(){
$(this).click().delay(5000);
});
});
above script doesnt work .
Is there any alternative?
I've tried Google it but I still couldn't figure it out, because I have little knowledge in JavaScript.
This will do it:
$(function(){
$('.clickThis').each(function(i, that){
setTimeout(function(){
$(that).click();
}, 5000*i );
});
});
Here's a version using a recursive setTimeout loop.
$(function() {
var click = $('.clickThis').toArray();
(function next() {
$(click.shift()).click(); // take (and click) the first entry
if (click.length) { // and if there's more, do it again (later)
setTimeout(next, 5000);
}
})();
});
The advantage of this pattern over setTimeout(..., 5000 * i) or a setInterval call is that only a single timer event is ever queued at once.
In general, repeated calls to setTimeout are better than a single call to setInterval for a few reasons:
setInterval calls can queue up multiple events even if the browser isn't active, which then all fire as quickly as possibly when the browser becomes active again. Calling setTimeout recursively guarantees that the minimum time interval between events is honoured.
With setInterval you have to remember the timer handle so you can clear it
You need to write an asynchronous setTimeout loop, for more information http://www.erichynds.com/javascript/a-recursive-settimeout-pattern/
Try to use this:
$(function () {
var items=$('.clickThis');
var length=items.length;
var i=0;
var clickInterval=setInterval(function(){
items.eq(i).click();
i++;
if(i==length)
clearInterval(clickInterval);
}, 5000);
});
var $clickthis=$(".clickthis");
var i= -1;
var delayed = setInterval(function(){
if (++i < $clickthis.length) $clickthis.eq(i).trigger("click");
else clearInterval(delayed);
}, 5000);
I am not sure but I think that setTimeout function should do the trick.
See here https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout
Try
$(function(){
$('.clickThis').each(function(_,i){
var me=$(this);
setTimeout(function(){me.click()},5000*i);
);
});
I have a slideshow function in jquery that I want to stop on a particular click event. The slideshow function is here:
function slider(){
setInterval(function(){
var cur = $('img.active');
cur.fadeOut('fast');
cur.removeClass('active');
cur.css('opacity','0');
cur.addClass("hidden");
var nextimg;
if (!cur.hasClass("last")){
nextimg = cur.next("img");
}
else {
nextimg = cur.prev().prev().prev();
}
nextimg.removeClass("hidden").fadeIn('slow').css('opacity','1').addClass('active');
},5000);
}
I have been reading about .queue but not sure how I can use it exactly, can I call my function from a queue and then clear the queue on a click event? I cannot seem to figure out the syntax for getting it to work of if thats even possible. Any advice on this or another method to stop a running function on a click would be appreciated.
For what it's worth, it's generally advisable to use a recursive setTimeout instead of a setInterval. I made that change, as well as a few little syntax tweaks. But this is a basic implementation of what I think you want.
// Store a reference that will point to your timeout
var timer;
function slider(){
timer = setTimeout(function(){
var cur = $('img.active')
.fadeOut('fast')
.removeClass('active')
.css('opacity','0')
.addClass('hidden'),
nextimg = !cur.hasClass('last') ? cur.next('img') : cur.prev().prev().prev();
nextimg.removeClass('hidden')
.fadeIn('slow')
.css('opacity','1')
.addClass('active');
// Call the slider function again
slider();
},5000);
}
$('#someElement').click(function(){
// Clear the timeout
clearTimeout(timer);
});
Store the result of setInterval in a variable.
Then use clearInterval to stop it.
Store the value returned by setInterval, say intervalId to clear it, your click handler should look like this:
function stopSlider() {
//prevent changing image each 5s
clearInterval(intervalId);
//stop fading the current image
$('img.active').stop(true, true);
}
I have $('.element').css("color","yellow") and I need that next event was only after this one, something looks like $('.element').css("color","yellow",function(){ alert(1); })
I need this because:
$('.element').css("color","yellow");
alert(1);
events are happen at one time almost, and this moment call the bug in animation effect (alert(1) is just here for example, in real module it's animation)
you can use promise
$('.element').css("color","yellow").promise().done(function(){
alert( 'color is yellow!' );
});
http://codepen.io/onikiienko/pen/wBJyLP
Callbacks are only necessary for asynchronous functions. The css function will always complete before code execution continues, so a callback is not required. In the code:
$('.element').css('color', 'yellow');
alert(1);
The color will be changed before the alert is fired. You can confirm this by running:
$('.element').css('color', 'yellow');
alert($('.element').css('color'));
In other words, if you wanted to use a callback, just execute it after the css function:
$('.element').css('color', 'yellow');
cb();
You can use setTimeout to increase the sleep time between the alert and the css like this:
function afterCss() {
alert(1);
}
$('.element').css("color","yellow");
setTimeout(afterCss, 1000);
This will make the alert appear 1 second after the css changes were committed.
This answer is outdated, so you might want to use promises from ES6 like the answer above.
$('.element').css("color", "yellow").promise().done(function(){
// The context here is done() and not $('.element'),
// be careful when using the "this" variable
alert(1);
});
There's no callback for jquery css function. However, we can go around, it's not a good practice, but it works.
If you call it right after you make the change
$('.element').css('color','yellow');
alert('DONE');
If you want this function has only been called right after the change, make an interval loop.
$('.element').css('color','yellow');
var detectChange = setInterval(function(){
var myColor = $('.element').css('color');
if (myColor == 'yellow') {
alert('DONE');
clearInterval(detectChange); //Stop the loop
}
},10);
To avoid an infinite loop, set a limit
var current = 0;
$('.element').css('color','yellow');
current++;
var detectChange = setInterval(function(){
var myColor = $('.element').css('color');
if (myColor == 'yellow' || current >= 100) {
alert('DONE');
clearInterval(detectChange); //Stop the loop
}
},10);
Or using settimeout as mentioned above/
use jquery promise,
$('.element').css("color","yellow").promise().done(function(){alert(1)});
I want to call a js function when there is no activity from user on the web page for specified amount of time. If there is activity from user then reset timeout. I tried to search but couldn't find anything in particular. I am familiar with setTimeout() and clearTimeout() and how they work. What I am looking for is where/how to monitor for user activity. Is there any event in which I can set and clear timer?
Thank you.
Edit #1:
This webpage has one input text box & one button. It's kind of regular chat page. When I say no user activity, I mean that the user has not typed anything in text box or has not pressed any button for specified amount of time. And one more thing that it is targeted for touch based smartphone devices.
Edit #2:
Thank you everyone for suggestions. I've implemented solution based on more than one answers provided. So I will give upvote to all answers that I've found helpful instead of accepting one as answer.
// Using jQuery (but could use pure JS with cross-browser event handlers):
var idleSeconds = 30;
$(function(){
var idleTimer;
function resetTimer(){
clearTimeout(idleTimer);
idleTimer = setTimeout(whenUserIdle,idleSeconds*1000);
}
$(document.body).bind('mousemove keydown click',resetTimer); //space separated events list that we want to monitor
resetTimer(); // Start the timer when the page loads
});
function whenUserIdle(){
//...
}
Edit: Not using jQuery for whatever reason? Here's some (untested) code that should be cross-browser clean (to a point; doesn't work on IE5 Mac, for example ;):
attachEvent(window,'load',function(){
var idleSeconds = 30;
var idleTimer;
function resetTimer(){
clearTimeout(idleTimer);
idleTimer = setTimeout(whenUserIdle,idleSeconds*1000);
}
attachEvent(document.body,'mousemove',resetTimer);
attachEvent(document.body,'keydown',resetTimer);
attachEvent(document.body,'click',resetTimer);
resetTimer(); // Start the timer when the page loads
});
function whenUserIdle(){
//...
}
function attachEvent(obj,evt,fnc,useCapture){
if (obj.addEventListener){
obj.addEventListener(evt,fnc,!!useCapture);
return true;
} else if (obj.attachEvent){
return obj.attachEvent("on"+evt,fnc);
}
}
This calls for a debouncer:
function debounce(callback, timeout, _this) {
var timer;
return function(e) {
var _that = this;
if (timer)
clearTimeout(timer);
timer = setTimeout(function() {
callback.call(_this || _that, e);
}, timeout);
}
}
Used like this:
// we'll attach the function created by "debounce" to each of the target
// user input events; this function only fires once 2 seconds have passed
// with no additional input; it can be attached to any number of desired
// events
var userAction = debounce(function(e) {
console.log("silence");
}, 2000);
document.addEventListener("mousemove", userAction, false);
document.addEventListener("click", userAction, false);
document.addEventListener("scroll", userAction, false);
The first user action (mousemove, click, or scroll) kicks off a function (attached to a timer) that resets each time another user action occurs. The primary callback does not fire until the specified amount of time has passed with no actions.
Note that no global flags or timeout variables are needed. The global scope receives only your debounced callback. Beware of solutions that require maintenance of global state; they're going to be difficult to reason about in the context of a larger application.
Note also that this solution is entirely general. Beware of solutions that apply only to your extremely narrow use case.
Most JavaScript events bubble, so you could do something like the following:
Come up with a list of all the events you'd consider to be "activity from the user" (e.g., click, mousemove, keydown, etc.)
Attach one function as an event listener for all of those events to document (or maybe document.body for some of them; I can't remember if that's an issue or not).
When the listener is triggered, have it reset the timer with clearTimeout/setTimeout
So you'd end up with something like this:
var events = ['click', 'mousemove', 'keydown'],
i = events.length,
timer,
delay = 10000,
logout = function () {
// do whatever it is you want to do
// after a period of inactivity
},
reset = function () {
clearTimeout(timer);
timer = setTimeout(logout, 10000);
};
while (i) {
i -= 1;
document.addEventListener(events[i], reset, false);
}
reset();
Note that there are some issues you'd have to work out with the above code:
It's not cross-browser compatible. It only uses addEventListener, so it won't work in IE6-8
It pollutes the global namespace. It creates a lot of excess variables that might conflict with other scripts.
It's more to give you an idea of what you could do.
And now there are four other answers, but I've already typed it all up, so there :P
You want to monitor events like mousemove, keypress, keydown, and/or click at the document level.
Edit: This being a smartphone app changes what events you want to listen for. Given your textbox and button requirements, I'd listen to oninput and then add the resetTimeout() call to the click handler for your button.
var inactivityTimeout = 0;
function resetTimeout() {
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(inactive, 300000);
}
function inactive() {
...
}
document.getElementById("chatInput").oninput = resetTimeout;
Something like this:
function onInactive(ms, cb){
var wait = setTimeout(cb, ms);
// Bind all events you consider as activity
// Note that binding this way overrides any previous events bound the same wa
// So if you already have events bound to document, use AddEventListener and AttachEvent instead
document.onmousemove = document.mousedown = document.mouseup = document.onkeydown = document.onkeyup = document.focus = function(){
clearTimeout(wait);
wait = setTimeout(cb, ms);
};
}
IE: http://jsfiddle.net/acNfy/
Activity in the bottom right frame will delay the callback.
I'm using a nifty little 'delay' method for this that I found in this thread
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
use like
delay(function(){ doSomethingWhenNoInputFor400ms(); },400);
Also, take a look at jQuery idleTimer plugin from Paul Irish (jquery.idle-timer.js). It was based on Nicholas C. Zakas' Detecting if the user is idle with JavaScript and YUI 3 article (idle-timer.js).
It looks at similar events to the other answers, plus a few more.
events = 'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove';
// activity is one of these events