How can I stop this blinking effect? - javascript

I have a Javascript function that loops to create a blinking effect by replacing a button image.
function blinkit() {
intrvl = 0;
for (nTimes = 0; nTimes < 500; nTimes++) {
intrvl += 1000;
t = setTimeout("document.getElementById('imgshowreport').src='report_icon.png';",intrvl);
intrvl += 1000;
t = setTimeout("document.getElementById('imgshowreport').src='report_icon2.png';",intrvl);
}
}
This serves the purpose but when the button is clicked I want the blinking to stop. How can I do this without the whole page being refreshed?

Using break to terminate the loop is useless because your loop will already have concluded and set all the timeouts before the user can click the button.
It would be better to use setInterval once rather than queueing up hundreds of individual timeouts. Then you can kill the interval in one fell swoop.
You should also not use string code, but a function:
var myInterval = null;
function blinkit() {
var i = 0;
myInterval = setInterval(function() {
document.getElementById('imgshowreport').src = (i % 2) ? 'report_icon2.png' : 'report_icon.png';
i++;
}, 1000);
}
document.getElementById('imgshowreport').onclick = function() {
if (myInterval != null) {
clearInterval(myInterval);
myInterval = null;
document.getElementById('imgshowreport').src = 'report_icon.png';
}
};
I haven't tested it for typos, but the basic logic is right.

You can use the break syntax
break;
or
nTimes = 500;

Try break
http://www.w3schools.com/js/js_break.asp

Related

stop executing loop on certain condition and wait for click, then continue

I need infinite loop(or other alternative) that increase my variable, and when this variable have certain value (100 or more) execution of this loop stop and wait for user click. After that, loop continues.
something like this:
var speed = 0;
for(i=0; i>=0; i++){
speed += 13;
if(speed >= 100){
// wait for this click
$(“.el”).click(()=> {
// some code
speed = 0;
});
}
//then continue loop with - speed = 0
}
written on javascript
Maybe can achieved with promises, await or something like that, but I can’t. I appreciate if anyone help me, thanks!
setTimeout seems like the right guy for the job.
To off a click use jQuery's .off()Method. Also, the .one() method to attach a callback only once:
const $btn = $("#btn");
const $log = $("#log");
let speed = 0;
let tO = null;
function clickHandle( evt ) {
console.log("CLICKED"); // Do something here
// ....
$btn.off("click", clickHandle); // Prevent further clicks
loop(); // restart the loop!
}
function loop() {
if (speed >= 100) {
clearTimeout(tO);
$btn.one("click", clickHandle); // Allow one click only
speed = 0; // Reset speed to 0
return; // Exit here, we're at >=100
}
speed += 13;
$log.text(speed);
tO = setTimeout(loop, 150); // Do +13 every 150ms
}
// init:
loop();
<button id="btn" type="button">Restart</button>
<div id="log"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I have not personally used JQuery but this is the code done recursively.
let speed = 0;
document.querySelector(".el").addEventListener("click", () => {
// some code
speed = 0;
// this restarts the loop
loop()
}, false)
function loop() {
speed += 13;
if (speed < 100) {
loop();
}
}
// to start the loop
loop();
<button class="el">Click ME</button>

How can I add a 5 second delay to this setInterval based sprite animation?

I have a sprite which runs using the setInterval method, It runs all the time and moves the css background position (x) by 100/(number of images -1) every interval of 60ms. When the position hits 96% i reset it to 0. Simple. This is the formula for animating a sprite with percentages.
Now I just want to add a 5 second delay between each time it runs (every time it hits 96% x position, wait 5 seconds and then run again). What is the easiest way to achieve this.. I tried wrapping the setInterval in another set interval but the problem here is that only runs it more often (and makes it go crazy). I know there is also a method called clearInterval and i am thinking maybe using that every few seconds would work but then how do i restart the animation afterwards?? I need it running over and over with a 5 second delay in between each run.
function animateAlways() {
var positionHeadDot = 0;
var interval = 60;
const diffHeadDot = 3.703704;
shadeSparkle = setInterval(() => {
/////////////////////HeadDot////////////////////////////////////
document.getElementById("imageHeadDot").style.backgroundPosition =
`${positionHeadDot}% 0%`;
if (positionHeadDot < 96) {
positionHeadDot = positionHeadDot + diffHeadDot;
}
else {
positionHeadDot = 0;
}
}, interval);
}
animateAlways()
Probably it is easier when you convert your setInterval code to use setTimeout. Then you can distinguish between the progress and final step and provide an adjusted timeout value:
function animateAlways() {
var positionHeadDot = 0;
var interval = 60;
var delay = 5000;
const diffHeadDot = 3.703704;
function animate() {
/////////////////////HeadDot////////////////////////////////////
document.getElementById("imageHeadDot").style.backgroundPosition =
`${positionHeadDot}% 0%`;
if (positionHeadDot < 96) {
positionHeadDot = positionHeadDot + diffHeadDot;
setTimeout(animate, interval);
}
else {
positionHeadDot = 0;
setTimeout(animate, delay); // 5 second wait.
}
}
animate();
}
You could add an outer setInterval, then use clearInterval to clear the inner interval instead of setting the position back to 0:
function animateAlways() {
var positionHeadDot = 0;
var interval = 60;
const diffHeadDot = 3.703704;
shadeSparkle = setInterval(() => {
/////////////////////HeadDot////////////////////////////////////
document.getElementById("imageHeadDot").style.backgroundPosition =
`${positionHeadDot}% 0%`;
if (positionHeadDot < 96) {
positionHeadDot = positionHeadDot + diffHeadDot;
} else {
clearInterval(shadeSparkle);
}
}, interval);
}
animateAlways();
setInterval(animateAlways, 5000);
#imageHeadDot {
background-image: url('https://www.w3schools.com/CSSref/smiley.gif');
width: 600px;
height: 50px;
border: 3px solid black;
}
<div id="imageHeadDot"></div>

How to run a javascript function X seconds?

I am using setInterval to run a Javascript function that generates a new, random integer in a div. the timer starts when I click on the div. I am having problems with stopping it form generating new numbers after five seconds.
Using setTimeout, I hide the div after 5 seconds; that stops random numbers, but I lose the div.
How can I efficiently stop the generating of numbers in the div, and not hide it?
HTML:
<div id="div" onmousedown='F();'>Click here</div>
JS:
function F(){
var div = document.getElementById("div");
setInterval(function(){
var number = Math.floor(Math.random()*28) ;
div.innerHTML = number;
}, 1000);
setTimeout(function(){
div.style.display = 'none';
},5000);
};
Just use a counter to keep track of the number of times the interval has ticked and then use clearInterval to stop it:
var count = 0;
var intervalID = setInterval(function() {
// generate your random number
count++;
if (count === 5) {
clearInterval(intervalID);
}
}, 1000);
Something hastily written, but what you want to do is keep track of your interval handle and then clear it. You can do this with a setTimeout
var forXsecs = function(period, func) {
var handle = setInterval(func, 1000);
setTimeout(function() { clearInterval(handle); }, period * 1000);
}
The timing is not perfect. Matt's answer would also work.
Another option is a slight change on Matt's answer that removes setInterval and just uses timeouts.
var count = 0;
var forXsecs = function(period, func) {
if(count < period) {
func();
count++;
setTimeout(function() {forXsecs(period, func);}, 1000);
} else {
count = 0; //need to reset the count for possible future calls
}
}
If you just want to simply let it run once each second and that 5 times you can do it like this:
HTML:
<div id="5seconds"></div>
JS:
var count= 0;
setInterval(function(){
if(count < 5){
document.getElementById('5seconds').innerHTML = Math.random();
count++
}
},1000);
This will generate a random number each second. until 5 seconds have passed
you should use clearInterval to stop the timer.
To do so, you pass in the id(or handle) of a timer returned from the setInterval function (which creates it).
I recommend clearing the interval timer (using clearInterval) from within the function being executed.
var elm = document.querySelector("div.container");
var cnt = 0;
var timerID;
function generateNumber()
{
cnt += 1;
elm.innerText = cnt;
if (cnt >= 5) {
window.clearInterval(timerID);
}
}
timerID = window.setInterval(generateNumber, 1000);
.container {display:block; min-width:5em;line-height:5em;min-height:5em;background-color:whitesmoke;border:0.1em outset whitesmoke;}
<label>1s Interval over 5s</label>
<div class="container"></div>

Add delay between 'for' loop iterations

I'm trying to implement basic 60 sec counter(A p element with idcounter), that is triggered after a button(counter_start()) is pressed.But I want delay of 1 sec between this and make sure this updates in browser window in real-time
<script type="text/javascript">
function counter_start(){
x=0
for(i=0;i<60;i++){
x++;
document.getElementById("counter").innerHTML=x;
}
}
</script>
P.S: There might be other simple methods of implementing a timer.But it's not about timer...actually I'm a student and trying to figure out the architecture and mechanism of this.
EDIT: please post tested versions of the code, as some of em' posted below DO NOT update in real time
Try this Example
Hope it will work for u
JS
for(i = 1; i <= 3; i++)
{
(function(i){
setTimeout(function(){
alert(i);
}, 1000 * i);
}(i));
}
Javascript operates synchronously in the browser.
You need to use setTimeout or setInterval to schedule the for loop's body to be called every second. I'm using setTimeout in the below example for easier "garbage collection"; we will never reschedule the tick to happen after we don't need to update things anymore.
<script type="text/javascript">
var counter = 0;
function counter_tick() {
if(counter < 60) {
counter++;
document.getElementById("counter").innerHTML = counter;
setTimeout(counter_tick, 1000); // Schedule next tick.
}
}
function counter_start() {
counter_tick(); // First update, also schedules next tick to happen.
}
</script>
It sounds like you are looking for a way to pause the current thread, which isn't possible in JavaScript and would probably be a bad idea anyway (the user's browser would lock up while the thread was paused).
A timer is really the way to go with this, otherwise you are fighting the way the language is intended to work.
There is no sleep-function in JS. But you can use window.setTimeout to call a function in given intervals:
function counter_start(){
// get current value
var value = document.getElementById("counter").innerHTML*1;
// leave function if 60 is reached
if(value == 60) {
return;
}
// set the innerHTML to the last value + 1
document.getElementById("counter").innerHTML=value+1;
// call next iteration
window.setTimeout(function(){counter_start()}, 100);
}
counter_start();
JSFiddle-Demo
For-loops run to completion, so you wouldn't usually use one for this.
You just need a timer and a variable to increment:
var maketimer = function(){
var tick = 0,
interval_ms = 1000,
limit = 10,
id;
return {
start: function(){
var timer = this;
console.log('start');
id = setInterval(function(){
if(tick === limit){
timer.stop();
timer.reset();
return;
}
tick += 1;
console.log(tick);
}, interval_ms);
},
stop: function(){
console.log('stop');
clearInterval(id);
},
reset: function(){
console.log('reset');
tick = 0;
}
};
};
var t = maketimer();
t.start();
If you really need to use a for-loop, then you could use a generator function. They're part of the proposed ES6 spec., and you'll need Firefox 26+ to try this out. However the only point of doing this would be to learn about generator functions.
var maketimer = function(){
var interval_ms = 1000,
limit = 10,
id,
loop,
it;
loop = function*(){
var i;
for(i=1; i<=limit; i+=1){
yield i;
}
};
it = loop();
return {
start: function(){
var timer = this;
console.log('start');
id = setInterval(function(){
var tick = it.next();
console.log(tick.value);
if(tick.done){
timer.stop();
timer.reset();
return;
}
}, interval_ms);
},
stop: function(){
console.log('stop');
clearInterval(id);
},
reset: function(){
console.log('reset');
it = loop();
}
};
};
var t = maketimer();
t.start();
Try this::
var x=0;
var myVar;
function myTimer() {
x++;
document.getElementById("counter").innerHTML = x;
if(x==60)
clearInterval(myVar);
}
function counter_start(){
myVar=setInterval(function(){myTimer()},1000);
}

Canvas issues with updating

<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;">
<script type="text/javascript">
window.onload = function() {
var ctx = document.getElementById("ctx").getContext("2d");
function createText(words) {
var LENGTH = words.length;
var LOOPS = LENGTH;
var reader = 0;
position = 10;
while( LOOPS > 0) {
letter = words.substr(reader,1);
setTimeout(ctx.fillText(letter,position,10),100);
position += 6;
reader += 1;
LOOPS -= 1;
}
}
createText("Hello, how are you?");
}
</script>
</canvas>
I want it to do kind of like a typing animation where it paused for a fraction of a second before each letter is printed, but instead it loads all at the same time. What am I doing wrong?
So there were a few things making this not work for you, for setTimeout your ctx.fillText was being called right away, as soon as the loop hit it. To stop that you need to wrap it in a function so it will be called during the timeout.
setTimeout(function(){
// your logic here.
}, 100);
However if you do that you will run into the common issue where you will only get the last letter due to the way variable scoping works in JavaScript. To fix that you need to wrap your function in a closure and pass the values to it.
// loop start
a++;
b++;
setTimeout(
(function (a,b) {
return function () {
// some logic that uses a and b
}
})(a, b), 100);
// loop end
The last thing that happens is your timeout is set to 100.. so it will all still happen at once. Meaning every timeout is going to fire after 100ms since the creation loop is so fast. In order to solve this you need to save the delay somewhere and increase that in the loop so they happen after one another. For example the first one will be delayed 100ms, and the next one 200ms, then 300, ect.
// loop start
a++;
b++;
// Increase the time delay each loop iteration
timeDelay += 100;
setTimeout(
(function (a,b) {
return function () {
// some logic that uses a and b
}
})(a, b), timeDelay);
// loop end
Full working code and demo
Live Demo
window.onload = function () {
var ctx = document.getElementById("ctx").getContext("2d");
function createText(words) {
var LENGTH = words.length;
var LOOPS = LENGTH;
var reader = 0;
var timeDelay = 100;
position = 10;
while (LOOPS > 0) {
letter = words.substr(reader, 1);
setTimeout((function (letter, position) {
return function () {
ctx.fillText(letter, position, 10);
}
})(letter, position), timeDelay);
position += 6;
reader += 1;
LOOPS -= 1;
timeDelay += 100;
}
}
createText("Hello, how are you?");
}

Categories