setInterval on resize - javascript

I have the below code:
var intervalId = "";
var isRunning = false;
var iCount = 0;
function animation() {
switch (iCount++ % 2) {
case 0:
$('.class1').removeClass("is-active");
$(".class2").addClass("is-active");
break;
case 1:
$('.class2').removeClass("is-active");
$(".class1").addClass("is-active");
break;
}
isRunning = true;
}
if (window.innerWidth > 1024) {
intervalId = setInterval(animation, 3000);
}
$(window).on("orientationchange resize", function () {
debounce(function () {
if (window.innerWidth < 1024) {
if (isRunning == true) {
clearInterval(intervalId);
isRunning = false;
}
} else if (window.innerWidth > 1024) {
if (isRunning == false) {
intervalId = setInterval(animation, 3000);
}
}
}, 250);
});
What I'm trying to get, is on a 1024+ screen the setInterval is fired, anything below 1024 isn't fired. But on resize to lower than 1024 the setInterval still being fired.
Any help would be greatly appreciated.

The isRunning logic is useless and redundant with intervalId being defined or not. You're using two variables for the same thing, and that's overkill.
Besides, you test window.innerWidth twice : is it <1024 or is it >1024 ? The second test is useless, and what happens if it's exactly 1024?
This block code makes things clearer and simpler :
debounce(function () {
if (window.innerWidth < 1024) {
clearInterval(intervalId);
} else {
if(!intervalId) intervalId = setInterval(animation, 3000);
}
})

I got it working by using this code for my resize function.
$(window).on("orientationchange resize", debounce(function () {
if (window.innerWidth < 1024) {
clearInterval(intervalId);
intervalId = "";
} else {
if (!intervalId) intervalId = setInterval(animation, 3000);
}
}));

Related

Adding timeout to a loop

I have a function that will perform an action when the timer reaches 5000ms:
var timer = new Timer(function () {
console.log("refreshingBid");
refreshBid();
}, 5000);
timer.pause();
if (isElementInViewport() === true) {
console.log("element in view");
timer.resume();
} else {
timer.pause();
console.log("element is out of view")
}
//I am trying to loop this 5 times with the 5000ms delay - the code I am using for this is:
for (i=0;i<=5;i++)
{
MyFunc();
}
It seems regardless of whether I put the for loop in the timer or whether I put the timer inside the for loop the result is the same where all 5 loops happen instantaneously instead of with a delay of the timer being applied? I'm not sure what i'm doing wrong here... Any help would be appreciated!
Sorry, edit to include the complete code below:
<script>
var iframe2 = document.getElementById('postbid_if');
function isElementInViewport() {
var el = document.getElementById('postbid_if')
console.log(el)
var rect = el.getBoundingClientRect();
console.log(rect)
return rect.bottom >= 0 &&
rect.right >= 0 &&
rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
rect.top < (window.innerHeight || document.documentElement.clientHeight);
}
function Timer(callback, delay) {
var timerId, start, remaining = delay;
this.pause = function () {
window.clearTimeout(timerId);
remaining -= new Date() - start;
};
this.resume = function () {
start = new Date();
window.clearTimeout(timerId);
timerId = window.setTimeout(callback, remaining);
};
this.resume();
}
for (i = 0; i <= 5; i++) {
MyFunc();
}
var timer = new Timer(function () {
console.log("refreshingBid");
refreshBid();
}, 5000);
timer.pause();
if (isElementInViewport() === true) {
console.log("element in view");
timer.resume();
} else {
timer.pause();
console.log("element is out of view")
}
</script>
It's because it's looping through quickly 5 times then all 5 loops are delaying after the 5 seconds. The timeout pauses it after 5 seconds, not for 5 seconds up front.
Perhaps you could revise your code in this way to achieve the timer based iterations as required:
//Track the current iteration
var i = 0;
function MyFunc() {
var timer = new Timer(function () {
console.log("refreshingBid");
refreshBid();
// The current timer has completed. If the current
// iteration is less than 5...
if(i < 5) {
i++;
// .. then start another timer for the next iteration
MyFunc();
}
}, 5000);
timer.pause();
if (isElementInViewport() === true) {
console.log("element in view");
timer.resume();
} else {
timer.pause();
console.log("element is out of view")
}
}
// Start the first iteration
MyFunc();

Making a timer with code that can easily be reset

I'm making a shot clock for my school's basketball team. A shot clock is a timer that counts down from 24 seconds. I have the skeleton for the timer right now, but I need to have particular key bindings. The key bindings should allow me to rest, pause, and play the timer.
var count=24;
var counter=setInterval(timer, 1000);
function timer()
{
count=count-1;
if (count <= 0)
{
clearInterval(counter);
return;
}
document.getElementById("timer").innerHTML=count + " secs";
}
I'm not sure what you meant by "rest" the timer, I interpret this as "pause", so:
Space = Pause / Play.
R = Reset.
var
count=24,
counter = setInterval(timer, 1000),
running = true;
function timer() {
count -= 1;
if (count <= 0) {
clearInterval(counter);
}
document.getElementById("timer").innerHTML = count + " secs";
}
window.addEventListener("keydown", function(e) {
switch(e.keyCode) {
case 32: // PLAY
running ? clearInterval(counter) : counter = setInterval(timer, 1000);
running = !running;
break;
case 82: // RESET
clearInterval(counter);
document.getElementById("timer").innerHTML = 24 + " secs";
count = 24;
running = false;
}
});
<div id="timer">24 secs</div>
I am not able to comment yet, but I recommend checking out this post Binding arrow keys in JS/jQuery
The linked post explains how to bind arrow keys using js/jquery. Using http://keycode.info/ you can find out the keycodes of your desired keys and replace the current values then continue to build your code from there.
Here is my code sample: http://codepen.io/anon/pen/vLvWJM
$(document).ready(function() {
var $timer = $('#timer');
var $timerStatus = $('#timerStatus');
var timerValue = 24;
var intervalId = null;
var timerStatus = 'stopped';
if(!$timer.length) {
throw 'This timer is missing a <div> element.';
}
$(document).keydown(function(k) {
if(k.which == 80) {
if(timerStatus === 'playing') {
clearInterval(intervalId);
timerStatus = 'stopped';
updateTimerStatus();
return;
}
intervalId = setInterval(function() {
playTimer();
timerStatus = 'playing';
updateTimerStatus();
}, 1000);
} else if(k.which == 82) {
clearInterval(intervalId);
resetTimer();
updateText();
timerStatus = 'stopped';
updateTimerStatus();
}
});
function playTimer() {
if(timerValue > 0) {
timerValue--;
updateText();
}
}
function resetTimer() {
timerValue = 24;
}
function updateText() {
$timer.html(timerValue);
}
function updateTimerStatus() {
$timerStatus.html(timerStatus);
}
});
<div id="timerStatus">stopped</div>
<div id="timer">24</div>

Making text blink a certain number of times?

I'm trying to make this blinking text stop after 3 seconds (or 3-5 blinks). I've set the blink rate to about the right speed, but cannot figure out how to make it stop.
Here's the code:
$('.blink').each(function() {
var elem = $(this);
setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
Any suggestions?
I've compiled a jQuery fiddle here: http://jsfiddle.net/M4Fcd/173/
setInterval goes on indefinitely - or until stopped.
What you need to do is capture the intervalID when you create the interval and then clear the interval after you are done with it
var intervalID = setInterval(function....);
// when done
clearInterval(intervalID);
In your particular case:
$('.blink').each(function() {
var elem = $(this);
// count the blinks
var count = 1;
var intervalId = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
// increment counter when showing to count # of blinks and stop when visible
if (count++ === 3) {
clearInterval(intervalId);
}
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
Updated fiddle http://jsfiddle.net/M4Fcd/186/
You could also use fadeIn/fadeOut like this
$('.blink').each(function() {
var elem = $(this);
elem.fadeOut(100)
.fadeIn(100)
.fadeOut(100)
.fadeIn(100)
.fadeOut(100)
.fadeIn(100);
});
jsFiddle
$('.blink').each(function() {
var elem = $(this);
refreshIntervalId = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
setTimeout(function(){
clearInterval(refreshIntervalId);
}, 3000)
fiddle: http://jsfiddle.net/M4Fcd/176/
try this:
var i = 0;
var blink;
$('.blink').each(function() {
var elem = $(this);
blink = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
i++;
if(i >= 3){
clearInterval(blink);
}
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
Fiddle
Ok, there is better way. You can just toggle css class with visibility: hidden, the code gets simpler and than if you want to stop when visible/not visible just need to check with hasClass.
$('.blink').each(function() {
var elem = $(this),
timer = 0,
interval = 200,
stopAfter = 3000,
intervalId = setInterval(function() {
elem.toggleClass('blink');
if(timer > stopAfter && !elem.hasClass('blink')) {
clearInterval(intervalId);
}
timer += interval;
}, interval);
});
fiddle: http://jsfiddle.net/M4Fcd/183/
Now you can stop it when it's visible or not, but the idea is pretty the same.
$('.blink').each(function() {
var elem = $(this),
timer = 0,
interval = 200,
stopAfter = 3000;
refreshIntervalId = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
if(timer > stopAfter) {
clearInterval(refreshIntervalId);
}
} else {
elem.css('visibility', 'hidden');
}
timer += interval;
}, interval);
});
fiddle: http://jsfiddle.net/M4Fcd/180/
I think I have the shortest answer.
function blinkElement(elm, interval, duration) {
elm.style.visibility = (elm.style.visibility === "hidden" ? "visible" : "hidden");
if (duration > 0) {
setTimeout(blinkElement, interval, elm, interval, duration - interval);
} else {
elm.style.visibility = "visible";
}
}
To blink for 3 seconds in the rate of 200 milliseconds.
blinkElement(element, 200, 3000);

adding wait for a loop in javaScript

I wanna run a loop in javaScript like this
for (conditions) { do something; wait for a second
}
How to make the portion of the condition typed in bold (delaying the condition for a second) ?
timeTillWarning = 10;
setTimeout(looping, 1000);
function looping() {
if (count > 0) {
count--;
setTimeout(looping, 1000);
}
}
var i = 100;
var interval = setInterval(function () {
// do something
i--;
if (i == 0) clearInterval(interval);
}, 1000);

How do I correctly use setInterval and clearInterval to switch between two different functions?

For practice I am trying to display a number that increments from 0 - 9, then decrements from 9 - 0, and infinitely repeats.The code that I have so far seems to be close, but upon the second iteration the setInterval calls of my 2 respective functions countUp and countDown seem to be conflicting with each other, as the numbers displayed are not counting in the intended order... and then the browser crashes.Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Algorithm Test</title>
</head>
<body onload = "onloadFunctions();">
<script type = "text/javascript">
function onloadFunctions()
{
countUp();
setInterval(countUp, 200);
}
var count = 0;
function countUp()
{
document.getElementById("here").innerHTML = count;
count++;
if(count == 10)
{
clearInterval(this);
countDown();
setInterval(countDown, 200);
}
}
function countDown()
{
document.getElementById("here").innerHTML = count;
count--;
if(count == 0)
{
clearInterval(this);
countUp();
setInterval(countUp, 200);
}
}
</script>
From 0 - 9, up and down: <div id = "here"></div>
</body>
</html>
You need to capture the return value from setInterval( ... ) into a variable as that is the reference to the timer:
var interval;
var count = 0;
function onloadFunctions()
{
countUp();
interval = setInterval(countUp, 200);
}
/* ... code ... */
function countUp()
{
document.getElementById("here").innerHTML = count;
count++;
if(count === 10)
{
clearInterval(interval);
countUp();
interval = setInterval(countUp, 200);
}
}
#Claude, you are right, the other solution I proposed was too different from original code. This is another possible solution, using setInterval and switching functions:
function onloadFunctions() {
var count = 0;
var refId = null;
var target = document.getElementById("aux");
var countUp = function() {
target.innerHTML = count;
count ++;
if(count >= 9) {
window.clearInterval(refId);
refId = window.setInterval(countDown, 500);
}
}
var countDown = function() {
target.innerHTML = count;
count --;
if(count <= 0) {
window.clearInterval(refId);
refId = window.setInterval(countUp, 500);
}
}
refId = window.setInterval(countUp, 500);
}
clearInterval(this);. You can't do that. You need to save the return value from setInterval.
var interval;
function onloadFunctions()
{
countUp();
interval = setInterval(countUp, 200);
}
var count = 0;
function countUp()
{
document.getElementById("here").innerHTML = count;
count++;
if(count == 10)
{
clearInterval(interval);
countDown();
interval = setInterval(countDown, 200);
}
}
function countDown()
{
document.getElementById("here").innerHTML = count;
count--;
if(count == 0)
{
clearInterval(interval);
countUp();
interval = setInterval(countUp, 200);
}
}
try this:
...
<body onload = "onloadFunctions();">
<script>
var cup, cdown; // intervals
var count = 0,
here = document.getElementById("here");
function onloadFunctions() {
cup = setInterval(countUp, 200);
}
function countUp() {
here.innerHTML = count;
count++;
if(count === 10) {
clearInterval(cup);
cdown = setInterval(countDown, 200);
}
}
function countDown() {
here.innerHTML = count;
count--;
if(count === 0) {
clearInterval(cdown);
cup = setInterval(countUp, 200);
}
}
</script>
From 0 - 9, up and down: <div id = "here"></div>
</body>
you could also create a single reference to #here element. Use always === instead of ==
There are many ways to solve this problem, the following is my suggestion:
function onloadFunctions() {
var count = 0;
var delta = 1;
var target = document.getElementById("here");
var step = function() {
if(count <= 0) delta = 1;
if(count >= 9) delta = -1;
count += delta;
target.innerHTML = count;
window.setTimeout(step, 500);
}
step ();
}
PS: it's safer to use setTimeout than setInteval.
/** Tools */
const log = require('ololog').configure({
locate: false
})
let count = 0
let interval__UP
let interval__DOWN
function countUp () {
count++
log.green('countUp(): ', count)
if (count == 5) {
clearInterval(interval__UP)
interval__DOWN = setInterval(function () {
countDown()
}, 1000)
}
}
function countDown () {
count--
log.red('countDown(): ', count)
if (count == 0) {
clearInterval(interval__DOWN)
interval__UP = setInterval(function () {
countUp()
}, 3000)
}
}
function start () {
countUp()
log.cyan('start()')
interval__UP = setInterval(function () {
countUp()
}, 2000)
}
start()
Console Log shows it's working

Categories