I have 3 sequential divs to display on a page, the page loads showing div 1, by going onto the 2nd it starts a timer, when that timer runs out it goes back to the first div. Navigating through to the next div should start the timer again. The timer function works OK on the first page but on the second page when it is called it is already running from the previous div and therefore ticks the time down twice as fast, and on the last div 3 times.
How can I get it to stop the currently running function then restart it?
Thanks,
$scope.timeLeft = 0;
var timeoutRunner = function (timerLength) {
$scope.timeLeft = timerLength;
var run = function () {
if ($scope.timeLeft >= 1) {
console.log($scope.timeLeft);
$scope.timeLeft--
$timeout(run, 1000);
} else if ($scope.timeLeft == 0){
$scope.endTransaction();
}
}
run();
}
timeoutRunner(5);
You need to add some logic that calls $timeout.cancel(timeoutRunner);.
Not sure where you want to cancel your timeout exactly (view change? when you end the transaction?) But here is how you would do it:
$scope.timeLeft = 0;
var timeoutPromise = false;
var timeoutRunner = function (timerLength) {
$scope.timeLeft = timerLength;
var run = function () {
if ($scope.timeLeft >= 1) {
console.log($scope.timeLeft);
$scope.timeLeft--
timeoutPromise = $timeout(run, 1000);
} else if ($scope.timeLeft == 0){
$scope.endTransaction();
$timeout.cancel(timeoutPromise);
}
}
run();
}
timeoutRunner(5);
Each time I called the function it created a new instance of it and I was unable to stop it on demand so I found a way to say which instance I want running:
$scope.timeLeft = 0;
var instanceRunning = 0;
var timeoutRunner = function (timerLength, instance) {
$scope.timeLeft = timerLength;
instanceRunning = instance;
var run = function () {
if (instanceRunning == instance){
if ($scope.timeLeft < 7 && $scope.timeLeft > 0){
$('#timer-container').show();
} else {
$('#timer-container').hide();
}
if ($scope.timeLeft >= 1) {
console.log($scope.timeLeft);
$scope.timeLeft--
$timeout(run, 1000);
} else if ($scope.timeLeft == 0){
$scope.endTransaction();
}
}
}
run();
}
timeoutRunner(20, 1);
timeoutRunner(20, 2);
timeoutRunner(20, 3);
Related
The 'Win' and 'Draw' parts are showing up on time, but the 'Lost' part doesn't show the message 'you lost'until I click on an empty cell once again. Please check out my code and help me find any errors.
Below is my code:
Marked is a class that changes the opacity of the clicked cell.
1,2,3...are the id's of respective cells in the table(html).
I tried delay() too instead of setTimeout(), but it didn't work as well.
$(document).ready(function() {
var timer;
var x = 0;
$("td").click(function() {
if($(this).text()=='') {
$(this).text("0").addClass("marked");
x = 1;
}
}).click(function() {
if(x==1) {
timer = setTimeout(function() {
var choose = $("td").not(".marked");
var random = choose[Math.floor(Math.random()*choose.length)];
$(random).text("X").addClass("marked");
},1000);
x=0;
showResult();
}
});
function showResult() {
var one = $("#1").text();
var two = $("#2").text();
var three = $("#3").text();
var four = $("#4").text();
var five = $("#5").text();
var six = $("#6").text();
var seven = $("#7").text();
var eight = $("#8").text();
var nine = $("#9").text();
if(one==two && two==three)
result(one)
else if (four==five && five==six)
result(four)
else if(seven==eight && eight==nine)
result(seven)
else if (one==four && four==seven)
result(one)
else if (two==five && five==eight)
result(two)
else if (three==six && six==nine)
result(three)
else if (one==five && five==nine)
result(one)
else if(three==five && five==seven)
result(three);
else {
var z = $("td").not(".marked");
if(z.length == 0) {
$("p").text("Draw!");
$("td").removeClass("marked");
$("td").text("");
$("#demo1").append('<img src="https://media.tenor.com/images/54c63f726505bfdb455eb4c29e626ad8/tenor.gif">');
clearTimeout(timer);
}
}
}
function result(y) {
var result = y;
if(result=="X"){
clearTimeout(timer);
$("p").text("You Lost!");
$("td").removeClass("marked");
$("td").text("");
$("#demo1").append('<img src="https://media.tenor.com/images/08902a85a6107684f8614846f4a54218/tenor.gif">');
}
if(result=="0") {
$("td").text("");
$("p").text("You Won!");
$("#demo1").append('<img src="https://i.gifer.com/4OuC.gif">');
$("td").removeClass("marked");
clearTimeout(timer);
}
}
});
You are calling showResult immeadiately when the user clicked, so it cant't recognize the X put into the table one second later.
Just do:
$("td").click(function() {
[...]
}).click(function() {
if (x == 1) {
timer = setTimeout(function() {
var choose = $("td").not(".marked");
var random = choose[Math.floor(Math.random() * choose.length)];
$(random).text("X").addClass("marked");
/******** ADD ANOTHER CHECK HERE ********/
showResult();
}, 1000);
x = 0;
showResult();
}
});
It might also be a good idea to add a return to showResult that returns false when a result was achieved. This way you could do something like
x = 0;
if (showResult()) {
timer = setTimeout(function() {
[...]
}
}
And the user can't get a loose message right after a win message.
Also: Why do you need the 2 click listeners? You can just use the if statement in the top one and then you don't need the (x == 1)
Im having trouble getting my second function to react to the changes the first function brings.
var jumbotron = function(){
var jumbotronCounter = 1
var jumbotronSwitch = function(){
var jumbotronTimer = function(){
jumbotronCounter++
}
jumbotronTimer();
if (jumbotronCounter > 3){
jumbotronCounter = 1
}
console.log(jumbotronCounter);
}
setInterval(jumbotronSwitch,7000);
var jumbotronListener = function(){
if(jumbotronCounter = 1){
console.log('first');
}else if(jumbotronCounter = 2){
console.log('second');
}else if(jumbotronCounter = 3){
console.log('third');
}
};
jumbotronListener();
}
jumbotron();
Id like to use "jumbotronListener" to run some code when "jumbotronCounter" changes
jumbotronListener is indeed only running once. You can, instead, run it every time the interval runs:
var jumbotron = function () {
var jumbotronCounter = 1;
var jumbotronSwitch = function () {
var jumbotronTimer = function () {
jumbotronCounter++;
};
jumbotronTimer();
if (jumbotronCounter > 3) {
jumbotronCounter = 1;
}
// Execute the listener every time the interval runs
jumbotronListener();
console.log(jumbotronCounter);
};
setInterval(jumbotronSwitch, 7000);
// Run for the first time if you wish:
jumbotronListener();
// Set this as function so you can 'use it before declaring it'
function jumbotronListener() {
// You had invalid operators. = assigns and === compares (strictly)
if(jumbotronCounter === 1) {
console.log('first');
} else if(jumbotronCounter === 2) {
console.log('second');
} else if(jumbotronCounter === 3) {
console.log('third');
}
}
};
jumbotron();
You also had some missing semicolons in there, sometimes it's not a problem since JavaScript auto-inserts them, but sometimes it is, so it's a good idea to always make sure to manually insert them where they go.
I want my countdown to stop on the click of a submit button, i searched in some pages,
but I didn't found anything.
Here is the code i want to stop on click
function countDown (count) {
if (count > 0) {
var d = document.getElementById("countDiv");
d.innerHTML = count;
setTimeout (function() { countDown(count-1); }, 1000);
document.getElementById('tiempo').value = count;
}
else
document.location = "timeover.php";
}
document.getElementById("palabra").focus();
countDown(5);
</script>
You have to save reference to timeout (actually return value of timeout will be number) and use it to cancel timeout.
var timeout = window.setTimeout(function () {
// do something
}, 1000);
// clear timeout
window.clearTimeout(timeout);
You probably got the idea. By the way, you should probably look at setInterval method since it would be better in this situation. Interval will "tick" as long until you cancel it.
Try something like this:
var stopped = false;
function countDown (count) {
if (count > 0) {
var d = document.getElementById("countDiv");
d.innerHTML = count;
document.getElementById('tiempo').value = count;
if (!stopped) {
setTimeout (function() { countDown(count-1); }, 1000);
}
}
else
document.location = "timeover.php";
}
document.getElementById("palabra").focus();
document.getElementById("mySubmitId").onclick = function () {
stopped = true;
};
countDown(5);
I am now working on a piece of code of JavaScript which will be used to redirect a page with a shown counter. The problem is, when counter reaches 0, countDown() function gets in an infinite loop which causes the page to remain the same. And of course, I could not resolve the problem yet. Can anyone help?
You can see the problem here:
http://kibristaodtuvarmis.com/index.html
Code is shown below:
var time = 10;
var page = "http://blog.kibristaodtuvarmis.com";
function countDown()
{
if (time == 0)
{
window.location = page;
return(0);
}
else
{
time--;
gett("container").innerHTML = time;
}
}
function gett(id)
{
if(document.getElementById) return document.getElementById(id);
if(document.all) return document.all.id;
if(document.layers) return document.layers.id;
if(window.opera) return window.opera.id;
}
function init()
{
if(gett("container"))
{
setInterval(countDown, 1000);
gett("container").innerHTML = time;
}
else
{
setTimeout(init, 50);
}
}
document.onload = init();
EDIT:
I have done the below changes in countDown() function and problem is resolved:
var control = false;
function countDown()
{
if (time == 0 && control == false)
{
control = true;
window.location = page;
return(0);
}
else if (time > 0)
{
time--;
gett("container").innerHTML = time;
}
else
{
return(0);
}
}
I would do something like this:
var b = false;
if (time == 0 && b == false)
{
b = true;
window.location = page;
return(0);
}
Try this part of code for by replacing your complete javascript Code :
var time = 10;
var page = "http://blog.kibristaodtuvarmis.com";
function startCount() {
time = time - 1;
console.log(time);
document.getElementById("container").innerHTML = time;
startCounter();
}
function startCounter() {
if (time !== 0) {
setTimeout(function () {
startCount();
},1000);
} else {
location.href = page;
}
}
if (window.addEventListener) {
window.addEventListener("load", startCount, false);
} else if (el.attachEvent) {
window.attachEvent("load", startCount);
}
I tried it, It works.
Tell me your reply after testing.
Are you wanting it to stop at 0? Assign the setInterval to a var and then use clearInterval if 0
your setIinterval continues executing before change the window.location and then causes this loop because time is 0 and should launch window.location again
you should clear the interval
var IdInterval = setInterval(function () {
//.... code
}, 10000);
and after the first execution of countDown with time==0 then:
clearInterval(IdInterval);
I am trying to figure out a way to make my countdown timer restart at 25 all over again when it reaches 0. I dont know what I am getting wrong but it wont work.
Javascript
window.onload = function() {
startCountDown(25, 1000, myFunction);
}
function startCountDown(i, p, f) {
var pause = p;
var fn = f;
var countDownObj = document.getElementById("countDown");
countDownObj.count = function(i) {
//write out count
countDownObj.innerHTML = i;
if (i == 0) {
//execute function
fn();
//stop
return;
}
setTimeout(function() {
// repeat
countDownObj.count(i - 1);
},
pause
);
}
//set it going
countDownObj.count(i);
}
function myFunction(){};
</script>
HTML
<div id="countDown"></div>
try this, timer restarts after 0
http://jsfiddle.net/GdkAH/1/
Full code:
window.onload = function() {
startCountDown(25, 1000, myFunction);
}
function startCountDown(i, p, f) {
var pause = p;
var fn = f;
var countDownObj = document.getElementById("countDown");
countDownObj.count = function(i) {
// write out count
countDownObj.innerHTML = i;
if (i == 0) {
// execute function
fn();
startCountDown(25, 1000, myFunction);
// stop
return;
}
setTimeout(function() {
// repeat
countDownObj.count(i - 1);
}, pause);
}
// set it going
countDownObj.count(i);
}
function myFunction(){};
​
I don't see you resetting the counter. When your counter goes down to 0, it executes the function and return. Instead, you want to execute the function -> reset the counter -> return
You can do this by simply adding i = 25 under fn() :
function startCountDown(i, p, f) {
var pause = p;
var fn = f;
var countDownObj = document.getElementById("countDown");
countDownObj.count = function(i) {
// write out count
countDownObj.innerHTML = i;
if (i == 0) {
// execute function
fn();
i = 25;
// stop
return;
}
setTimeout(function() {
// repeat
countDownObj.count(i - 1);
},
pause
);
}
// set it going
in #Muthu Kumaran code is not showing zero after countdown 1 . you can update to this:
if (i < 0) {
// execute function
fn();
startCountDown(10, 1000, myFunction);
// stop
return;
}
The main reason for using setInterval for a timer that runs continuously is to adjust the interval so that it updates as closely as possible to increments of the system clock, usually 1 second but maybe longer. In this case, that doesn't seem to be necessary, so just use setInterval.
Below is a function that doesn't add non–standard properties to the element, it could be called using a function expression from window.onload, so avoid global variables altogether (not that there is much point in that, but some like to minimise them).
var runTimer = (function() {
var element, count = 0;
return function(i, p, f) {
element = document.getElementById('countDown');
setInterval(function() {
element.innerHTML = i - (count % i);
if (count && !(count % i)) {
f();
}
count++;
}, p);
}
}());
function foo() {
console.log('foo');
}
window.onload = function() {
runTimer(25, 1000, foo);
}