I've always had issues with setInterval:
$('li.item').live('click', function(){
//Need to work with Dyn created object
//clearInterval(itemClockInterval);
itemClockInterval = setInterval(function() {
deconInterval(_this.children('.timeleft'), time);
}, 1000);
});
There are multiple li's with the class "item". When clicked, the setInterval function updates a clock appended to that specific li.
My problem is that every time an li is clicked, the clock counts down twice as fast as before because an additional interval is running. I need all instances of the interval to be cleared before the new interval starts, but none of my solutions work.
I commented out one of the things I have tried, seeing as though the interval is not created until later this is problematic.
Store the result of setInterval() on the element using .data() and clear it on click.
$('li.item').live('click', function(){
$this = $(this);
var existing_timer = $this.data('clock');
if (existing_timer){
clearInterval(existing_timer);
}
itemClockInterval = setInterval(function() {
deconInterval($this.children('.timeleft'), time);
}, 1000);
$this.data('clock', itemClockInterval);
});
use a closure:
$('li.item').live('click', (function(){ //Need to work with Dyn created object
var itemClockInterval;
return function(){
if(itemClockInterval) clearInterval(itemClockInterval);
itemClockInterval = setInterval(function() {
deconInterval(_this.children('.timeleft'), time);
}, 1000);
};
})());
OR, use jQuery's data method:
$('li.item').live('click', function(ev){ //Need to work with Dyn created object
var itemClockInterval = $(ev.target).data("itemClockInterval")
if(itemClockInterval) clearInterval(itemClockInterval);
$(ev.target).data("itemClockInterval", setInterval(function() {
deconInterval(_this.children('.timeleft'), time);
}, 1000));
});
Use data to store the intervalID associated with that li...
$('li.item').live('click', function(){ //Need to work with Dyn created object
var itemClockIntervalID = $(this).data("itemClockIntervalID");
if (itemClockIntervalID != "undefined") {
clearInterval(itemClockIntervalID);
}
itemClockIntervalID = setInterval(function() { deconInterval(_this.children('.timeleft'), time); }, 1000);
$(this).data("itemClockIntervalID", itemClockIntervalID);
});
Or use jQuery's ability to keep track of the timers for you as described here: http://plugins.jquery.com/project/timers. It automatically maintains an association between a jQuery object and your timer so it keeps track of the previous timer so you can clear the interval before setting a new one.
Related
I'm having issues getting clearInterval to work when I try to bind it to a button click. Also, apparently the function is starting on it's own... Here's my code
var funky = setInterval(function() {
alert('hello world');
}, 2000);
$('#start').click(function() {
funky();
});
$('#stop').click(function() {
clearInterval(funky);
});
Here's a js fiddle
You have forgot to add jquery library and have made wrong assignment, it needs to be inside callback function.
Working example:
var funky;
$('#start').click(function() {
funky = setInterval(function() {
alert('hello world');
}, 2000);
});
$('#stop').click(function() {
clearInterval(funky);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="start">start</button>
<button id="stop">stop</button>
First off, yes, when you assign a variable to a function, it self invokes.
Secondly, your click events are not working because you need assign the interval to the variable on the click, not invoke the function - there is no function to invoke, as you would see if you looked at your developer console.
Lastly, it is good practice to wrap the jQuery code in the document ready function to ensure all of your event handlers get bound properly.
$(function () {
var funky;
$('#start').click(function() {
funky = setInterval(function() {
alert('hello world');
}, 1000);
});
$('#stop').click(function() {
clearInterval(funky);
});
});
You're saving the wrong value. Try this:
var funky = function() {
alert('hello world');
}
var funkyId = setInterval(funky, 2000);
$('#start').click(function() {
funky();
});
$('#stop').click(function() {
clearInterval(funkyId);
});
Here I am giving you the idea.
declare a variable e.g. let x;
create a function which you want to bind with setInterval.
e.g.
function funky() {
alert("Hello World");
}
assign start.onclick to a function which will assign the setInterval to x.
e.g start.onclick = function(){
clearInterval(x); // to prevent multiple interval if you click more than one
x = setInterval(funky, 2000); // assign the setInterval to x
};
assign stop.onclick to clearInterval(x) to stop the interval.
e.g. stop.onclick = function() {
clearInterval(x); // to stop the interval
};
That's it. Easy right.
So I have two element first and second; I'm trying to let them take turns to appear; I have following code;
setTimeout(setInterval(function(){
$(".first").hide();
$(".second").show();
},20000),10000)
setTimeout(setInterval(function(){
$(".first").show();
$(".second").hide();
},20000),0)
it seems these codes doesn't work, can someone tell me what's wrong?
i found an alternative:
var d=0;
setInterval(function(){
if(d==0){
d=1
$(".first").hide();
$(".second").show();
}else if(d==1){
d=0
$(".first").show();
$(".second").hide();
}
},10000)
Your setTimeout() callbacks need to be actual function references like function() {setInterval(...)}. The way you had it, you were executing the setInterval() immediately and then passing the results to setTimeout() which was doing nothing:
setTimeout(function() {
setInterval(function(){
$(".first").hide();
$(".second").show();
},20000),10000);
But, there is a much better way to implement this with only a single timer:
(function() {
var flag = true;
setInterval(function() {
flag = !flag;
$(".first")[flag ? "hide" : "show"]();
$(".second")[flag ? "show" : "hide"]();
}, 10000);
})();
Or, if you set the hide/show state opposite initially, then you can just use jQuery's .toggle() to reverse the visibility:
$(".first").show();
$(".second").hide();
setInterval(function() {
$(".first").toggle();
$(".second").toggle();
}, 10000);
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Below is a jQuery statement which hides a div element on it's click event. I'd like the element to fade out regardless if it isn't clicked after 5 seconds. Is there a simple way I can call the fadeOut function in the same expression or without the click event interfering with the animation?
$(".fadeOutbox").click(function(){
$(this).fadeOut('slow');
});
Most jQuery components are chain-able, your function as it stands returns a reference to the initial object.
You can achieve what you want simply by using:
$(".fadeOutbox").click(function () {
$(this).stop().fadeOut('slow');
}).delay(5000).fadeOut('slow');
Basically reads as onclick, fade out otherwise fade out after 5 seconds.
I assume this is inside another function that shows the box to begin with. This solution will hide the box after 5 seconds, or immediately upon clicking.
var $box = $('.fadeOutbox');
var fadeOut = function() {
clearTimeout(timeout);
$box.fadeOut('slow');
};
var timeout = setTimeout(fadeOut, 5000);
$box.click(fadeOut);
Save the fact that the user has clicked or not and test it in the timer
var isClicked = false;
setTimeout(function () {
if(!isClicked)
$(".fadeOutbox").fadeOut('slow');
}, 5000);
$(".fadeOutbox").click(function () {
isClicked = true;
});
Try this:
var wasClicked = false;
$(".fadeOutbox").click(function () { wasClicked = true; });
setTimeout(function () {
if(wasClicked = false)
$(".fadeOutbox").fadeOut('slow');
}, 5000);
Use a timeout not inside of the click handler:
setTimeout(function () {
$(".fadeOutbox").fadeOut('slow');
}, 5000);
Your jQuery code becomes:
// set a timeout for 5 seconds
setTimeout(function () {
$(".fadeOutbox").fadeOut('slow');
}, 5000);
// attach click handler
$(".fadeOutbox").on("click", function () {
$(this).fadeOut('slow');
});
JSFIDDLE
Edit to clarify:
var clear = setTimeout(function(){ $(".fadeOutbox").fadeOut('slow'); }, 5000);
$(".fadeOutbox").on('click', function(){
clearTimeout(clear);
});
Demo: http://jsfiddle.net/mGbHq/
Try holding a variable for the timeout and clear it every time the user clicks.
Working example
// Timeout variable
var t;
$('.fadeOutBox').click(function()
{
$box = $(this);
$box.fadeIn("fast");
// Reset the timeout
clearTimeout(t);
t = setTimeout(function()
{
$box.fadeOut("slow");
}, 5000);
});
Hope this helps you.
Wow, none of the answers gives the simple solution: Use setTimeout and cancel the timeout on click:
$(".fadeOutbox").click(function () {
// Cache the jQuery object
var $this = $(this);
// Do we already have a timer running?
var timer = $this.data("timer");
if (timer) {
// Yes, cancel it
clearTimeout(timer);
$this.removeData("timer");
}
// (You may want an `else` here, it's not clear)
// In five seconds, fade out
$this.data("timer", setTimeout(function() {
$this.removeData("timer");
$this.fadeOut('slow');
}, 5000));
});
I'm not 100% sure that the above is triggering on the events you want, but the two pieces of relevant code are this, which schedules the timed action:
// In five seconds, fade out
$this.data("timer", setTimeout(function() {
$this.removeData("timer");
$this.fadeOut('slow');
}, 5000));
and this, which cancels it (for instance, on click):
var timer = $this.data("timer");
if (timer) {
// Yes, cancel it
clearTimeout(timer);
$this.removeData("timer");
}
Try
$('#div').delay(5000).fadeOut(400)
Demo
My application reloads data every 500ms. How do I have to change the code to not reload every 500ms but to wait for 500ms after the last reload to trigger a new one?
App = Ember.Application.create({
ready: function() {
var switchboard = App.Switchboard.find(switchboard_id);
setInterval(function() {
switchboard.reload();
}, 500);
}
});
I have just done something similar. You should use activate property on your route (http://emberjs.com/api/classes/Ember.Route.html#method_activate).
Checkout this pull request: https://github.com/chrmod/rowmark/pull/2/files
Some example:
App.NoteRoute = Ember.Route.extend({
activate: function() {
this.interval = setInterval(function() {
this.get('controller').set('toSave', true);
}.bind(this), 5000);
}
})
UPDATE
I understand you wrong. Sorry for that.
First of all you need to know that find from Ember Model or Ember Data returns promises (http://emberjs.com/blog/2013/05/28/ember-data-0-13.html)
I think you can do such trick to implement that:
App = Ember.Application.create({
ready: function() {
var switchboard;
setInterval(function() {
switchboard = App.Switchboard.find(switchboard_id).then(function(){
setTimeout(function(){}, 499);
});
}, 1);
}
});
First of all we run setInterval to run this in infinity loop. Next in each loop iteration we find Switchboard and when Ember data loads from external server those data that run function that is passed to then. This function simply wait 499ms :)
I have a function which loops through rows in a table so that only one is shown at any given time.
I want to expand on this so that when I hover over the table, it shows all the rows, and then when I move away, it resumes showing one row at a time.
The Problem I have is that on hovering, the first function keeps going, is there a way to 'pause' the function. I've looked at various examples using ClearInterval(),but can't match them to my script.
//Calling The function that loops through the rows
function hideShow(time)
{
setInterval('showRows()',time);
};
//Set the time between each 'loop' and start looping
$(document).ready(function()
{
hideShow(2000);
}
);
//The hover function to show / hide all the rows
$(document).ready(function()
{
$('#dbTable1 tr').hover(function()
{
$('.Group td').removeClass('RoundBottom');
$('.Group').show();
},
function()
{
$('.Group td').addClass('RoundBottom');
$('.Group').hide();
}
);
}
);
Can anyone show me please how I can combine the two?
You need to keep track of the timer ID when you call setInterval:
var timerID;
function hideShow(time){
timerID = setInterval(showRows, time);
}
Then later on when you want to stop the repetition, call clearInterval and pass in that ID:
// ...
$('.Group td').removeClass('RoundBottom');
$('.Group').show();
clearInterval(timerID);
},
function()
{
hideShow(2000);
$('.Group td').addClass('RoundBottom');
// ...
You could just check the hovering state before doing anything else, like this:
function showRows() {
if (isHovering) {
return;
}
// ...
}
The isHovering variable is just a boolean with current hovering state, that could be set by your callback function.
With the above approach, you can set your timer only once and forget about it.