I have trouble with timer in button click. When i click button startpause() method is called there i set start timer and stop timer. It works fine when I click button normally(one click after sometime another click) but when I click the button again and again speedly the timer starts to jump with 2-3 secs. Seems like more than one timer is running.. Anyone have any idea....?? here time is my timer method
function startpause() {
if(FLAG_CLICK) {
setTimeout(tim,1000);
FLAG_CLICK = false;
}
else {
clearTimeout(ti);
FLAG_CLICK = true;
}
}
function tim() {
time.innerHTML = t;
t = t + 1;
ti= setTimeout("tim()", 1000);
}
Try this:
// assuming you declared ti and t out here, cuz I hope they're not global
var t = 0;
var ti;
var running = false;
function startpause() {
clearTimeout(ti);
if(!running) {
ti = setTimeout(tim,1000);
running = true;
} else {
running = false;
}
}
function tim() {
time.innerHTML = t;
t = t + 1;
ti = setTimeout(tim,1000);
}
You can read more about the .setTimeout() here: https://developer.mozilla.org/en/docs/DOM/window.setTimeout
Also, see the jsfiddle I just created: http://jsfiddle.net/4BMhd/
You need to store setTimeout somewhere in order to manipulate it later.
var myVar;
function myFunction()
{
myVar=setTimeout(function(){alert("Hello")},3000);
}
function myStopFunction()
{
clearTimeout(myVar);
}
ref http://www.w3schools.com/js/js_timing.asp
Maybe you must change this:
if(FLAG_CLICK) {
setTimeout(tim,1000);
FLAG_CLICK = false;
}
to:
if(FLAG_CLICK) {
tim();
FLAG_CLICK = false;
}
It seems works for me normally
Related
I'm trying the make a chrome extension in javascript. So far, my popup.js looks like this:
let bg;
let clock;
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('button1').addEventListener('click', butClicked);
bg = chrome.extension.getBackgroundPage();
//clock = document.getElementById("label1");
});
let timeStamp;
let isClockRunning = false;
function butClicked() {
let test = bg.getURL();
document.getElementById('test').innerHTML = test;
timeStamp = new Date();
isClockRunning = !isClockRunning;
runCheckTimer();
}
function runCheckTimer() {
var handle;
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
function updateClock() {
let seconds = bg.returnTimeSince(timeStamp);
document.getElementById("label1").innerHTML = "Seconds: " + seconds;
}
The program works just fine when I click the button once; it starts the timer. But when I click the button the second time, timeStamp gets set to 0, but the updateClock keeps running at the same interval; the interval doesn't get cleared even though I'm toggling the isClockRunning boolean. It's almost as if javascript is forgetting to run the else if part in runCheckTimer(). How can I fix this?
EDIT: On a sidenote, am I doing the timer thing the right way? Or is there a better way to do it? I basically want a timer to keep ticking every second since you've pressed the button, and then when you click it again it'll stop and reset to 0.
You have scoped handle to runCheckTimer. When runCheckTimer starts, it will create a new handle every time.
Move handle outside of the function.
var handle;
function runCheckTimer() {
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
I am using setTimeout to run a slideshow. I want to have button to stop it. The markup is:
<h3> Modest Mouse at Fillmore in Miami <h3>
<div>
<img id="photo" src="http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg" alt= "Modest Mouse at Fillmore">
<span>•</span>
<span>•</span>
<span>•</span>
</div>
<button onclick="stopShow();">Stop</button>
The JS is:
var aSlideShowPics = ["http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmoude7.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmouse8.jpg"
];
// Timer for SlideShow
var i = 0;
function changeSlide() {
var stopShowID;
stopShowID = window.setTimeout(function() {
newPic = aSlideShowPics[i];
$("#photo").attr("src", newPic);
i++;
if (i < aSlideShowPics.length) {
changeSlide(); // recursive call to increment i and change picture in DOM.
} else {
i = 0; // reset loop to keep slideshow going
changeSlide(); // Recursive call on loop end
}
function stopShow() {
window.clearTimeout(stopShowID);
}
}, 3000)
}
changeSlide();
I keep getting a reference error on button click of no stopShow. I've tried putting the clearTimeout function in several places in code but get same error. Perhaps a new set of eyes can see my error. Here is the jsfiddle. Thanks for any input.
Move the stopShow outside of the timeout and outside of changeSlide.
var stopShowID;
function changeSlide() {
stopShowID = window.setTimeout( function(){}, 3000);
}
function stopShow() {
if(stopShowID) {
window.clearTimeout(stopShowID);
stopShowID = null;
}
}
the stopShow() method does not exists at the window level, it only exists within the body of changeSlide(). Directly attach it to window
window.stopShow = function() ...
or pull it out of the closure
var i = 0;
var stopShowId;
function stopShow() {
window.clearTimeout(stopShowID);
}
function changeSlide() {
stopShowID = window.setTimeout(function() {
if (i >= aSlidesShowPics.length - 1)
i = 0;
var newPic = aSlideShowPics[i++];
$("#photo").attr("src", newPic);
changeSlide();
}, 3000);
}
I couldn't launch your jsfidle example, so I update the content of your code, 2 issues raised:
1- Your stopShow was undefined, so I attached it to window scope:
window.stopShow = stopShow;
2- For your ClearTimeout scope issue: your stopShowID variable was inside your function changeSlide: your stopShow was using a local copy. I basically put it as a global variable so both function could have access to it.
var aSlideShowPics = ["http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmoude7.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmouse8.jpg"
];
// Timer for SlideShow
var stopShowID;
var i = 0;
function stopShow() {
window.clearTimeout(stopShowID);
}
window.stopShow = stopShow;
function changeSlide() {
stopShowID = window.setTimeout(function() {
newPic = aSlideShowPics[i];
$("#photo").attr("src", newPic);
i++;
if (i < aSlideShowPics.length) {
changeSlide(); // recursive call to increment i and change picture in DOM.
} else {
i = 0; // reset loop to keep slideshow going
changeSlide(); // Recursive call on loop end
}
}, 3000)
}
changeSlide();
working jsfiddle:
http://jsfiddle.net/fLw2a4vs/44/
I have 31 images and I want to display them one after another as the background of a div. I only want it to change when the user hovers over the div. My problem right now is that it just flips through all the images really fast. I am attempting to use setTimeout, but it isn't working. How can I make the delay work?
The name of the div is About_Me_Block and the images are called frame1.gif,frame2.gif ...etc
Here is my code:
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
var counter = 0;
while (hoverAnimate[0]) {
console.log(counter);
setTimeout(changeImg(counter), 1000);
counter++;
if (counter === 32)
hoverAnimate[0] = false;
}
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
setTimeout doesn't wait for the function to end, it works lile threading in other languages.
To achieve a what you want, you need to call setTimeout from the changeImg function.
var counter = 0;
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
counter = 0;
changeImg();
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
function changeImg() {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
counter++;
if (counter < 32 && hoverAnimate[0]) {
setTimeout(changeImg, 1000);
} else {
hoverAnimate[0] = false;
}
}
the reason they happen all at once is because while statement doesn't have delay, so all setTimeout will be set up at the same time, thus, calling changeImg all at once.
To solve this problem, you can replace setTimeout with setInterval. Instead of using while, you can just call setInterval like
var counter = 0;
var myTimer = setInterval(changeImg, 1000);
and update counter inside changeImg every time it gets called. After looping, don't forget to
clearInterval(myTimer)
It seems you need to read up on how setTimeout works. It essentially places a reminder to run a function after a given amount of milliseconds have passed. So, when you do setTimeout(changImg(counter), 1000) you are calling changImg(counter) which returns undefined. Therein producing this setTimeout(undefined, 1000) which is why it flips really fast.
So, you can use bind to allow the function to be called later with that parameter built in. Also, make sure you remove the reminders once done with clearTimeout.
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = false, id;
function loop(counter) {
if(hoverAnimate || counter < 32) {
changeImg(counter);
id = setTimeout(loop.bind(this, counter++), 1000);
}
}
$('#About_Me_Block').mouseenter(function() {
hoverAnimate = true;
id = setTimeout(loop.bind(this, 0), 1000);
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate = false;
// Don't want a reminder for a random counter to wake up.
clearTimeout(id);
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
Two methods for timers - setTimeout and SetInterval (single / repeating)
// setInterval is also in milliseconds
var intervalHandle = setInterval(<yourFuncToChangeImage>,5000);
//this handle loop and make example loop stop
yourelement.yourEvent = function() {
clearInterval(intervalHandle);
};
I am currently setting up two buttons, start and stop for a jquery loop on html5. The start button works perfectly but whatever I try the 'stop' button remains inactive. I have seen many examples about stopping the loop but none seems to resolve the issue in the button being unresponsive. Sorry if this is such a simple question, but as a student I am quite frustrated and thus asking. cheers
"use strict";
var current_banner_num = 1;
$(document).ready(function(){
$("#banner-base").css("visibility","hidden");
$("#banner-"+current_banner_num).show();
var next_button = $("#start").button();
var stop_button = $("#stop").button();
next_button.click(function(){
var timer = setInterval(myCode, 2000);
function myCode() {
//$("#banner-"+current_banner_num).hide();
$("#banner-"+current_banner_num).fadeTo(800, 0);
if (current_banner_num == 4) {
current_banner_num = 1;
}
else {
current_banner_num++;
}
$("#banner-"+current_banner_num).fadeTo(800, 1);
}
});
stop_button.click(function(){
function abortTimer(){
clearInterval(timer);
}
});
});
You are just defining a function again and again here. Just get rid of the function in the event handler:
stop_button.click(function(){
clearInterval(timer);
});
This would execute the clearInterval(), while the code in your original question just defines a function, but doesn't call or do anything as you said. Hope it gets solved.
I think you have 2 problems in your code. timer variable is not visible outside of next_button.click(function(){ ... }); because it is local for this function, so you need to make it a little bit global; second problem is that in stop_button.click(function(){ ... }); you just declare function abortTimer but do not call it (in general, it is not necessary to declare that function). I think your code should be like:
"use strict";
var current_banner_num = 1;
$(document).ready(function(){
$("#banner-base").css("visibility","hidden");
$("#banner-"+current_banner_num).show();
var next_button = $("#start").button();
var stop_button = $("#stop").button();
var timer = null;
next_button.click(function(){
timer = setInterval(function(){
//$("#banner-"+current_banner_num).hide();
$("#banner-"+current_banner_num).fadeTo(800, 0);
if (current_banner_num == 4) {
current_banner_num = 1;
}
else {
current_banner_num++;
}
$("#banner-"+current_banner_num).fadeTo(800, 1);
}, 2000);
});
stop_button.click(function(){
clearInterval(timer);
});
});
Also it wasn't necessary to declare function myCode in nextButton function, so i clear it too for you
Use a global variable instead of a local one ,unwrap the clearInterval function
"use strict";
var current_banner_num = 1;
$(document).ready(function(){
$("#banner-base").css("visibility","hidden");
$("#banner-"+current_banner_num).show();
var next_button = $("#start").button();
var stop_button = $("#stop").button();
var timer = null;
next_button.click(function(){
timer = setInterval(myCode, 2000);
function myCode() {
//$("#banner-"+current_banner_num).hide();
$("#banner-"+current_banner_num).fadeTo(800, 0);
if (current_banner_num == 4) {
current_banner_num = 1;
}
else {
current_banner_num++;
}
$("#banner-"+current_banner_num).fadeTo(800, 1);
}
});
stop_button.click(function(){
clearInterval(timer);
});
});
This is a followup to this question, where I found out how to make code be repeated every x seconds. Is it possible to make an event that can change this? I.e. I have a checkbox which is meant to control whether this is repeated or not, so I figured I'd need something like this:
$(checkbox).bind("change", function() {
switch(whether if it is ticked or not) {
case [ticked]:
// Make the code repeat, while preserving the ability to stop it repeating
case [unticked]:
// Make the code stop repeating, while preserving the ability to start again
}
});
I have no idea what I could put in the cases.
You can do it by assigning your setInterval function to a variable.
var interval = setInterval(function() { }, 1000);
and then you can stop setInterval by
clearInterval(interval);
p.s.
to start your interval you need to call var interval = setInterval(function() { }, 1000); again
You can either stop and start the interval:
var timer;
function start() {
timer = window.setInterval(function(){
// do something
}, 1000);
}
function stop() {
window.clearInterval(timer);
}
start();
$(checkbox).bind("change", function() {
if ($(this).is(':checked')) {
start();
} else {
stop();
}
});
Or you can have a flag causing the interval to skip the code:
var enabled = true;
var timer = window.setInterval(function(){
if (!enabled) {
// do something
}
}, 1000);
$(checkbox).bind("change", function() {
enabled = $(this).is(':checked');
});
function fooFunc() {
$('#foo').text(+new Date());
}
var id;
var shouldBeStopped = false;
$('input').change(function() {
if (shouldBeStopped)
clearInterval(id);
else
id = setInterval(fooFunc, 200);
shouldBeStopped = !shouldBeStopped;
});
Live DEMO