Javascript for() not working - javascript

I am trying to make a progress bar with Javascript. I am using a for loop to run the code:
var prog = document.getElementById("progressbar").max;
var progg = document.getElementById("progressbar");
function runAnimation(){
for(var i=0; i < prog; i++){
var hit = progg.value;
hit++;
}
};
This should make the value of the progressbar increment each time the function runs, but it doesn't work. I am not getting any errors in the console. How can I make the progressbar's value rise incrementally?

For an "animated" effect, you can recursively call a setTimeout, based on the current value and max value of your progress bar. Something like:
var progg = document.getElementById("progressbar");
function runAnimation(){
setTimeout(function() {
if (progg.value <= progg.max) {
progg.value++;
runAnimation();
}
}, 10);
};
runAnimation();
Changing your timeout value (10 in the above example) will increase/decrease the progress bar.
Here's a fiddle: http://jsfiddle.net/cL7nygsr/
For a more interesting use of setTimeout (since the above is just basically setInterval), call it after an operation has completed before calling your next iteration. Here's an updated fiddle which includes a random update of the progress bar.
http://jsfiddle.net/cL7nygsr/2/

var b = document.getElementById('progress').max;
window.setInterval(a,1000);
function a() {
document.getElementById('progress').value++;
if (document.getElementById('progress').value >= b) {
window.clearInterval(a);
}
}
Here is code to increment progress bar value every 1 second, you can change to 2 second by replacing 1000 with 2000.

You're not doing anything with your hit variable once you increment it. You want to do this instead:
for (var i = 0; i < prog; i++) {
progg.value++;
}

Related

Creating a for loop that loops over and over =

So I have a weird problem (as I can do this using dummy code, but cannot make it work in my actual code) -
The concept is simple - I need a for loop that upon hitting its max "I" number reverts "I" to 0 again and creates a loop over and over -
DUMMY CODE:
for(i=0;i<10;i++){
console.log(i);
if(i === 10){
i = 0
}
}
Now for the longer code (sorry)
function reviewF(){
// add ID to each of the objects
reviews.forEach((e, i)=>{
e.id = i
})
// get the elements to be populated on page
var name = document.querySelector('p.name');
var date = document.querySelector('p.date');
var rating = document.querySelector('.rating_stars');
var review = document.querySelector('p.review_content_text');
// reverse the array - so the newest reviews are shown first (this is due to how the reviews where downloaded)
var reviewBack = reviews.slice(0).reverse();
// start the loop - go over each array - take its details and apply it to the elements
/**
* THIS IS WHAT I WOULD LIKE TO LOOP OVER FOREVER
*
* **/
for (let i = 0; i < reviewBack.length; i++) {
(function(index) {
setTimeout(function() {
// document.getElementById('reviews').classList.remove('slideOut')
name.classList.remove('slideOut')
date.classList.remove('slideOut')
rating.classList.remove('slideOut')
review.classList.remove('slideOut')
name.classList.add('slideIn')
date.classList.add('slideIn')
rating.classList.add('slideIn')
review.classList.add('slideIn')
name.innerHTML = reviewBack[i].aditional_info_name;
date.innerHTML = reviewBack[i].Date;
rating.innerHTML = '';
review.innerHTML = reviewBack[i].aditional_info_short_testimonial;
if(reviewBack[i].aditional_info_short_testimonial === 'none'){
reviewBack.innerHTML='';
}
var numberOfStars = reviewBack[i].aditional_info_rating;
for(i=0;i<numberOfStars;i++){
var star = document.createElement('p');
star.className="stars";
rating.appendChild(star);
}
setTimeout(function(){
// document.getElementById('reviews').classList.add('slideOut')
name.classList.add('slideOut')
date.classList.add('slideOut')
rating.classList.add('slideOut')
review.classList.add('slideOut')
},9600)
}, i * 10000)
})(i);
// should create a infinite loop
}
console.log('Loop A')
}
// both functions are running as they should but the time out function for the delay of the transition is not?
reviewF();
EDITS >>>>>>>>
Ok so I have found a hack and slash way to fix the issue - but its not dry code and not good code but it works.....
this might make the desiered effect easier to understand
reviewF(); // <<< this is the init function
// this init2 function for the reviews waits until the reviews have run then
// calls it again
setTimeout(function(){
reviewF();
}, reviews.length*1000)
// this version of the innit doubles the number of reviews and calls it after that amount of time
setTimeout(function(){
reviewF();
}, (reviews.length*2)*1000)
From trying a bunch of different methods to solve this issue something I noticed was when I placed a console.log('Finished') at the end of the function and called it twice in a row (trying to stack the functions running..... yes I know a horrid and blunt way to try and solve the issue but I had gotten to that point) - it called by console.log's while the function was still running (i.e. the set time out section had not finished) - could this have something to do with it.
My apologies for the rough code.
Any help here would be really great as my own attempts to solve this have fallen short and I believe I might have missed something in how the code runs?
Warm regards,
W
Why not simply nest this for loop inside a do/while?
var looping = True
do {
for(i=0;i<10;i++){
console.log(i);
}
if (someEndCondition) {
looping = False;
}
}
while (looping);
I would think that resetting your loop would be as simple as setting "i = 0" like in the dummy code. So try putting the following into your code at the end of the for loop:
if(i === 10){
i = 0;
}

While loop and setInterval()

I am trying to mix the initial string and randomly compare the string's elements with the right elements on the right indexes, and if true push them into a set, to reconstruct the initial string. Doing this I met the problem that while loop does nothing just crushng the browser. Help me out with this.
function checker() {
var text = document.getElementById("inp").value;
var a = [];
var i = 0;
while (a.length < text.length) {
var int = setInterval((function() {
var rnd = Math.floor(Math.random() * text.length);
if (text[rnd] === text[i]) {
a.push(text[rnd]);
clearInterval(int);
i++;
}
}), 100)
}
}
P.S. I need the setInterval() function because I need the process to happen in exactly the same periods of time.
So, you stumbled into the pitfall most people hit at some point when they get in touch with asynchronous programming.
You cannot "wait" for an timeout/interval to finish - trying to do so would not work or block the whole page/browser. Any code that should run after the delay needs to be called from the callback you passed to setInterval when it's "done".
In my answer its doing exactly what you want - creating exactly the same string by randomly mixing the initial, and also using setInterval. You didn't write where you want the result, so you have it written in the console and also in another input field with id output_string.
HTML:
<input id="input_string" value="some_text" />
<input id="output_string" value="" readonly="readonly" />
JavaScript:
function checker() {
var text = document.getElementById("input_string").value;
var result = '';
// split your input string to array
text = text.split('');
var int = setInterval((function() {
var rnd = Math.floor(Math.random() * text.length);
// add random character from input string (array) to the result
result += text[rnd];
// remove used element from the input array
text.splice(rnd, 1);
// if all characters were used
if (text.length === 0) {
clearInterval(int);
console.log(result);
document.getElementById("output_string").value = result;
}
}), 100);
}
checker();
DEMO
Honestly, I have no idea what you are trying to do here, but you seem to have lost track of how your code is operating exactly.
All your while loop does, is creating the interval, which is ran asynchronous from the loop itself.
In other words, the only way your while condition equates to false, is after multiple 100ms intervals have elapsed. 100 miliseconds is an eternity when comparing it to the speed of 1 loop iteration. We're looking at 1000s of iterations before your first setInterval even triggers, not something a browser can keep up with, let alone wait several of these intervals before you change a.length.
Try more like this:
function checker() {
var text = document.getElementById("inp").value;
var a = [];
var i = 0;
// start to do a check every 100ms.
var interv = setInterval(function() {
var rnd = Math.floor(Math.random() * text.length);
if (text[rnd] === text[i]) {
a.push(text[rnd]);
i++;
}
// at the end of each call, see if a is long enough yet
if(a.length > text.length){
clearInterval(interv); // if so, stop this interval from running
alert(a); // and do whatever you need to in the UI.
}
}, 100);
}
}

Problems using setInterval and clearInterval more than once

I'm getting confused with what's happening here. The quiz works fine the first time. After the first play, though, I get all sorts of problems. I want to click the same button,"#start2", to start and also restart the quiz, ie clear the timer, put all variables back to 0 etc, and display the first question. As if the page had been refreshed, basically.
Instead, I'm getting faster ticking, the timer is incrementing on correct guess and so on. Horrible.
I've used modulo to measure how many times the "#start2" div is clicked. On first click, start timer. On second click - I want to reset the timer. Third click - start timer, and so on.
Any help is massively appreciated.
var n = 0;
var x = 0;
var p = 0;
var incTime;
function a(n) {
var x,y,z;
x = Math.floor((Math.random() * 3))
if(x == 0){y = 1; z = 2}else if(x == 1){y = 0; z = 2}else{y = 0; z = 1}
$("#question_holder2").text(questions[n].q);
$(".answer_holder2").eq(x).text(questions[n].a).data('answer', 'a');
$(".answer_holder2").eq(y).text(questions[n].b).data('answer', 'b');
$(".answer_holder2").eq(z).text(questions[n].c).data('answer', 'c');
}
$(document).ready(function() {
//timing element
function startTimer(x){
$("#start2").text(x);
}
$("#start2").click(function(){
var setTimer;
p++;
//if it's been clicked before
if(p%2 === 0){
clearInterval(setTimer);
$("#start2").text("Start");
n = 0;
x = 0;
a(n);
alert("okay");
}else if(p%2 !== 0){
//never been clicked before
a(n);
setTimer = setInterval(function(){startTimer(x=x+1)}, 1000);
$('.answer_holder2').click(function() {
//correct answer given
if ($(this).data('answer') === 'a') {
n++;
if (n < questions.length) {
a(n);
} else {
alert("End of quiz!");
clearInterval(setTimer);
$("#start2").text("You took " + x + " seconds, you answered " + n + " questions correctly, with - incorrect answers given.");
x = 0;
n = 0;
a(n);
}
}else{
//incorrect answer given
$(this).fadeTo(1000,0.4);
var timeString = $("#start2").text();
var incTime = (timeString * 1) + 5;
$("#start2").text(incTime);
startTimer(incTime);
x = incTime;
};
});
};
});
});
You have this:
$("#start2").click(function(){
var setTimer;
p++;
//if it's been clicked before
if(p%2 === 0){
clearInterval(setTimer);
//....
In this case, when you set to the clearInterval line, setTimer will always be 0, and not the id of a running timer. So this is not actually stopping any timer. If you don't stop the timer it will continue to run. So the function here:
setTimer = setInterval(function(){startTimer(x=x+1)}, 1000);
Will continue to run. So the next time you create a timer, you now have two timers updating x and it'll look like it's running faster.
Try this:
$(document).ready(function() {
var setTimer;
$("#start2").click(function(){
// the rest of your click handler code...
});
//timing element
function startTimer(x){
$("#start2").text(x);
}
}
Your setTimer variable needs to exist in a scope outside of your click handler. As you had it you were declaring a new variable every time so when you try and clear the timer, you are not actually clearing the timer.
Also: freakish's point about how you are reattaching the click handler is also a problem. You need to fix that too.
The answer is that bad things happen because of this:
$("#start2").click(function(){
// some code...
$('.answer_holder2').click(function() {
// some code...
});
});
When you click on #start2 new handler is attached to .answer_holder2. So after for example 3 clicks, .answer_holder2 has 3 handlers attached to it and when you click on it all 3 fire.
You're code is a bit complicated and I'm not going to give you a solution how to fix that. But I can give you a hint. Put inner .click outside of outer .click. You will have to change some code probably, but that has to be done.
EDIT What you could try ( as a fast fix, but not necessarly good ) is adding this:
$('.answer_holder2').off( "click" ).click(function() {
Additonally have a look at Matt's answer.

While loop only returning final result

while (counterInc < counter) {
window.setTimeout(function () {
$('#results').text(counterInc);
}, 3000);
counterInc++;
}
This code should increment the tag with ID results every 3000 milliseconds instead the while loop is running and returning the final result. For example instead of changing the text to 1, 2, 3, 4, 5,..n, it is changing the text to n. How would one have the loop update the text field every 1000 milliseconds with each increment instead of only the final result?
Try this
var counterInc = 0;
var counterMax = 10;
var timeoutId = window.setInterval(function() {
$('#results').text(counterInc++);
if (counterInc >= counterMax) {
window.clearInterval(timeoutId);
}
}, 500);​
http://jsfiddle.net/GufCs/4/
What was happening was you timeout updated the cell every three seconds, however, your loop can run through a ridiculous amount of numbers in 3 seconds, so it's long since complete by the time the function in setTimeout had run.
This will trigger the function every 500ms (change to 3000ms for your purposes) and only then will it increment the counterInc. Add it clears the Interval when it reaches counterMax.
The problem is that setTimeout() acts as an "independent thread". You set it and it executes once after the specified amount of time. In the mean time the "main thread" keeps running: so your counter will get increased in the meantime.
To understand the problem you need to understand what a closure is.
Here you want each time to pass a certain value not the one computed at the end of the loop scope.
So compute the value at the moment you declare the setTimout rather than when it is call you can do as follow: http://jsfiddle.net/lechevalierd3on/jhYm3/
var counter = 10;
var counterInc= 0;
while (counterInc < counter) {
window.setTimeout(function () {
var inc = counterInc;
return function(){
$('#results').text(inc);
}
}(counterInc), 1000 * counterInc);
counterInc++;
}​
while (counterInc < counter) {
window.setTimeout(function () {
$('#results').text(counterInc);
}, 3000 * counterInc++);
}

storing the value of setInterval

if I had a code like this
count=0
count2=setInterval('count++',1000)
the count2 variable would always set as 2 not the actual value of count as it increases every second
my question is: can you even store the value of the seInterval() method
The return value of setInterval() is an ID number that can be passed to clearInterval() to stop the periodically executed function from running another time. Here's an example of that:
var id = setInterval(function() {
// Periodically check to see if the element is there
if(document.getElementById('foo')) {
clearInterval(id);
weAreReady();
}
}, 100);
In your example, if you want count2 to have the same value as count, you could use:
var count = 0, count2 = 0;
setInterval(function() {
// I wrote this on two lines for clarity.
++count;
count2 = count;
}, 1000);
setInterval returns an ID which you can later use to clearInterval(), that is to stop the scheduled action from being performed. It will not be related to the count values in any way.
var count=0;
function incrementCount(){
count++;
}
setTimeout("incrementCount()", 1000);

Categories