SetInterval running even after i clear it - javascript

Im having a little trouble fixing a problem i have with setInterval.
I have a function that runs when i click an element on my website that sets var pass = 1;
if you look in color1(); there is a set Interval that clears itself when pass > 0; so if pass = 1; then it should clear itself, it does, but only after running the interval one more time.
so it - runs setInterval, clears setInterval, then runs the rest of the code in setInterval. What i need, is for setInterval to clear without running the code again.
Thanks in advance
function color1() {
var pass = 1;
var counter = 2;
var animationSpeed = 800;
var $colorContent = '.color-container-1 .color-content-container'
var colorInterval = setInterval(function() {
if (pass > 0) {
clearInterval(colorInterval);
}
$($colorContent).fadeOut(0);
$(($colorContent + '-' + counter)).fadeIn(animationSpeed);
++counter
if (counter === $($colorContent).length + 1) {
counter = 1;
}
}, 3000);
}

It should be like below, you should return the function. Here you have cleared the interval but you haven't stopped the execution
var colorInterval = setInterval(function() {
if (pass > 0) {
clearInterval(colorInterval);
return; //stop here so that it doesn't continue to execute below code
}
$($colorContent).fadeOut(0);
$(($colorContent + '-' + counter)).fadeIn(animationSpeed);
++counter
if (counter === $($colorContent).length + 1) {
counter = 1;
}
}, 3000);

Related

mouseover image stuck in loop

I have been making this JavaScript code to display multiple images in one frame on mouse over.
But I get stuck in the setInterval loop and the images keep on changing although I exited the frame.
It is definitely stuck in the function change().
I can not find a way to exit this as I move my cursor.
Could you give me a hand?
let start = 0;
const imageChange = document.querySelector(".image");
imageChange.addEventListener("mouseover", set_time);
imageChange.addEventListener("mouseout", end);
function set_time() {
setInterval(change, 1500);
}
function change() {
if (start < 3) {
console.log(start);
imageChange.src = "/img/image" + start + ".jpg";
start++;
} else {
start = 0;
}
}
function end() {
start = 0;
imageChange.src = "/img/image" + start + ".jpg";
}
You need to use clearInterval to stop the continuous execution of the function.
let intvl;
function set_time() {
intvl = setInterval(change, 1500);
}
function change() {
if (start < 3) {
console.log(start);
imageChange.src = "/img/image" + start + ".jpg";
start++;
} else {
start = 0;
}
}
function end() {
start = 0;
clearInterval(intvl);
imageChange.src = "/img/image" + start + ".jpg";
}

Starting timer when clicking first card of memory game

Ok I am trying to wrap up a project and the only thing holding me back is it that they call for the timer to start on clicking a match game. The timer starts when the HTML file loads which is not what the project wants and I have tried some methods but ends up freezing the game. I want the timer to be able to start when clicking a card.
var open = [];
var matched = 0;
var moveCounter = 0;
var numStars = 3;
var timer = {
seconds: 0,
minutes: 0,
clearTime: -1
};
//Start timer
var startTimer = function () {
if (timer.seconds === 59) {
timer.minutes++;
timer.seconds = 0;
} else {
timer.seconds++;
};
// Ensure that single digit seconds are preceded with a 0
var formattedSec = "0";
if (timer.seconds < 10) {
formattedSec += timer.seconds
} else {
formattedSec = String(timer.seconds);
}
var time = String(timer.minutes) + ":" + formattedSec;
$(".timer").text(time);
};
This is the code for clicking on a card. I have tried to include a startTimer code into this but doesn't work.
var onClick = function() {
if (isValid( $(this) )) {
if (open.length === 0) {
openCard( $(this) );
} else if (open.length === 1) {
openCard( $(this) );
moveCounter++;
updateMoveCounter();
if (checkMatch()) {
setTimeout(setMatch, 300);
} else {
setTimeout(resetOpen, 700);
}
}
}
};
And this class code I use for my HTML file
<span class="timer">0:00</span>
Try this: https://codepen.io/anon/pen/boWQbe
All you needed to do was remove resetTimer() call from the function that happens on page load and then just do a check in the onClick (of card) to see if the timer has started yet. timer.seconds == 0 && timer.minutes == 0.

How to change the speed of setInterval in real time

I would like to know how to change the speed of setInterval in real time e.g:
if (score < 10)
repeater = setInterval(function() {
spawnEnemy();
}, 1000);
if (score => 10)
repeater = setInterval(function() {
spawnEnemy();
}, 500);
I know this method doesn't work, but is there a way that I can achieve this some other way?
jsFiddle Demo
There is no way to change the interval speed itself once running. The only way to do it is to have a variable for the speed, and then clear the interval and start a new one with the new speed.
var speed = 500;
var changeSpeed = speed;
repeater = setInterval(repeaterFn, speed);
function repeaterFn(){
spawnEnemy();
if( changeSpeed != speed ){
clearInterval(repeater);
speed = changeSpeed;
repeater = setInterval(repeaterFn, speed);
}
}
function changeRepeater(){
changeSpeed = 700;
}
Another way would be to just use setTimeout rather than setInterval. Do the check every time so you can keep your speed logic in a seperate function.
var game_over = false;
var score = 0;
function getSpeedFromScore(score)
{
if (score > 20) {
game_over = true;
}
if (score < 10) {
return 1000;
} else {
return 500;
}
}
function spawnEnemyThenWait() {
if (!game_over) {
spawnEnemy();
var speed = getSpeedFromScore(score);
setTimeout(spawnEnemyThenWait, speed);
}
}
JS Fiddle http://jsfiddle.net/bq926xz6/
You can use clearInterval:
if (score < 10) {
clearInterval(repeater);
repeater = setInterval(spawnEnemy, 1000);
}
if (score => 10) {
clearInterval(repeater);
repeater = setInterval(spawnEnemy, 500);
}
But it depends on the context. If this snippet is executed more often, than it has to be, you will need some kind of mechanism to prevent it from resetting your interval all the time.
But there is (as I wrote in the comment to the question) no way to use clearInterval and change the interval itself. At least not without replacing it by a new interval as shown above.
You can use a game loop and track the spawn state in an enemy class:
// press f12 so see console
function Enemy() {
this.spawned = false;
this.spawnOn = 20;
this.tick = function () {
this.spawnOn = this.spawnOn - 1;
if (this.spawnOn == 0) {
this.spawned = true;
}
}
this.goBackToYourCage = function () {
this.spawnOn = Math.floor(Math.random() * 50) + 1;
this.spawned = false;
}
}
var enemy = new Enemy();
window.setInterval(function () {
enemy.tick();
if (enemy.spawned) {
console.log('spawned');
enemy.goBackToYourCage();
console.log('Next spawin in :' + enemy.spawnOn);
}
}, 100);
http://jsfiddle.net/martijn/qxt2fe8y/2/

setInterval doesnt tigger inner script on first time run

Maybe I'm not properly understanding setInterval but I have made a kind of slideshow script, as below:
var i = 0;
setInterval(function() {
$('.slide').fadeOut('slow').delay(200);
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i++;
if(i == 5){
i = 0;
}
}, 4000);
This works, except for the first run - no slides will display for the first 4 seconds.
See Fiddle here: http://jsfiddle.net/vpa89snf/6/
Is there anyway I can trigger whats inside the setInterval function when it runs the first time round?
Use setTimeOut instead of setInterval for better performance, inspect the sample below:
Here is working jsFiddle.
var i = -1;
var totalSlide = $('.slide').length-1;
var slideTimer = 0;
function nextFrame() {
i == totalSlide ? i = -1 : i;
i++;
$('.slide').fadeOut(200);
$('.slide').eq(i).fadeIn(200);
slideTimer = setTimeout(nextFrame,4000);
}
$('#holder').addClass('isAni');
nextFrame();
// play / pause animation
$('#holder').click(function() {
if ( $(this).hasClass('isAni') ) {
$(this).removeClass('isAni');
clearTimeout(slideTimer);
}else{
$(this).addClass('isAni');
nextFrame();
}
});
You need to run the function and not wait for the 4 first seconds:
var i = 0;
function doSomething() {
$('.slide').fadeOut('slow').delay(200);
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i = (i + 1) % 5;
}
$document.ready(function () {
setInterval(doSomething, 4000);
doSomething(); // run it!
});
JSFIDDLE.
This is how setInterval is executed. It runs your function after x milliseconds set as 2nd parameter.
What you have to do in order to show the first slide is to have the 1rst slide fadein like below:
var i = 0;
$('.slide:eq(' + i + ')').fadeIn('slow').delay(2000);
i++;
setInterval(function() {
...
}, 4000);

Timer not running more than once

For some reason when I run the below script for the first time, the timer doesn't activate again for a second time, any idea why?
var timer = 0;
$(document).ready(function() {
$('#search').keypress(function() {
if(timer == 0) { $('#sel').html('<iframe src="search.php?p=' + $('#search').val() + '"></iframe>'); }
timer = 1;
setTimeout('timer = 0;', 2000);
});
});
Regards
Matthew
setTimeout only runs once. You probably want setInterval.
$('#search').keypress(function() {
if(timer == 0) { setTimeout('clearTimeout(this);timer = 0;', 2000); $('#sel').html('<iframe src="search.php?p=' + $('#search').val() + '"></iframe>'); }
timer = 1;
});
Running the timer inside it fixed it well :)

Categories