for (var i=list.length; i>=0; i--){
//do something....
}
I want to use a setInterval to make this process take 1 whole min no matter how many items are in the list. So if there are 10 items it would trigger every 6sec, 30items, every two seconds, etc.
Thanks for any help!
Something like this could be done:
var list = [1,2,3,4,5,6,7,8,9,10];
var timeFrame = 60000;
var interval = timeFrame / (list.length-1);
var i = 0;
(function iterate () {
if (list.length > i) {
console.log(list[i]);
i++;
}
setTimeout(iterate, interval);
})();
JsFiddle Demo
I am not sure if this is what you're looking for, but this will "iterate" through all items in the list, without using for loop, in the given timeframe. The function will always "call itself" using setTimeout. The timeout is calculated in the beginning based on the number of items.
This solution is much more "trustable" than setInterval. The next timeout will be set when the previous action is already done, so it won't stack up.
var totalItem = list.length;
setInterval(function(){ alert('');}, 60000/totalItem);
You'd do
function code(i) {
return function() { alert(i); };
}
var period = 60 * 1000 / (list.length - 1);
for (var i=list.length; i>=1; i--){
setTimeout(code(list[i - 1]), period * (i - 1));
}
Try something like the following:
var interval = 2;
for (var i=list.length; i>=0; i--){
setTimeout(your_code_here(), i*interval);
}
Related
I have a li that I want to animate while hovering over.
I try to get the previous li item with ยง(this).prevAll("li") and then use JQuery to change the style.
For this I want to get the IDs of the previous items. My current code looks like this:
$("#somediv li").hover(function()
{
var object = $(this).prevAll("li");
var i;
for (i = object.length - 1; i >= 0; i--) {
dowork(i);
}
function dowork(i) {
setTimeout(function() {
console.log(i);
$("#"+object[i].id+"").addClass("animateprogress");
}, 500 * i);
}
Output of the for loop is 5,4,3,2,1,0 (depending on object length). The timeout output though reverses this to 0,1,2,3,4,5. I don't know why tough. I just want to output 5,4,3,2,1,0 with 500ms delay to style my previous li elements.
You'll have to distinguish between the delay you want and the object index you want. Both are now the same variable i in your function, but they should be somewhat opposite.
So for example do:
$("#somediv li").hover(function() {
var object = $(this).prevAll("li");
var i;
for (i = 0; i < object.length; i++) {
// pass a delay that increases with each iteration,
// and pass an index that decreases with each iteration:
dowork(500 * i, object.length - 1 - i);
}
function dowork(delay, index) {
setTimeout(function() {
console.log(index);
$("#"+object[index].id).addClass("animateprogress");
}, delay);
}
});
try:
setTimeout(animate, (object.length - 1 - i) * 500)
instead.
you can use these codes too
$("#somediv li").hover(function()
{
var object = $(this).prevAll("li");
var i;
for (i = object.length - 1; i >= 0; i--) {
dowork(i,(object.length-i)*500);
}
function dowork(i,d) {
setTimeout(function() {
console.log(i);
$("#"+object[i].id+"").addClass("animateprogress");
}, d);
}
It will give the result you expect.
The issue was on delay time you was adding greater time for greater number which is opposite of your expectation
I have four different button effects where each effect are declared in a variable.
Therefore, I bring all of these four variables and place them within an array called arr in which is used in the clickByItself() function using Math.floor(Math.random()) methods.
Without the for loop, the code clicks by itself randomly in one of the four buttons every time I reload the page.
function clickByItself() {
let random = Math.floor(Math.random() * arr.length);
$(arr[random]).click();
}
However, using the for loop I am not being able to make these clicks one-by-one within the maximum of 10 times.
var blueButtonEffect = code effect here;
var redButtonEffect = code effect here;
var greenButtonEffect = code effect here;
var yellowButtonEffect = code effect here;
var arr = [blueButtonEffect, redButtonEffect, greenButtonEffect, yellowButtonEffect];
//will click on buttons randomly
function clickByItself() {
let random = Math.floor(Math.random() * arr.length)
var i;
for (i = 0; i < 10; i++) {
$(arr[random]).click();
setTimeout(clickByItself(), 1000);
}
}
The final output with the current code above is the four buttons being clicked at the same time, not one-by-one.
So, how can I have this function to press a random button by 10 times one-by-one with one second of interval from each click?
To fix your code you need:
A base case for your recursion
Pass a function reference to setTimeout. Currently, you are executing clickByItself and passing its return value (which is undefined) to setTimeout.
Do not use setTimeout in a loop without increasing the time by a factor of i, as the for loop will queue all the function calls at the same time
Alternatively, you can use a "times" argument to avoid looping
You could try something like
function clickByItself(times = 0) {
let random = Math.floor(Math.random() * arr.length)
$(arr[random]).click();
if (++times < 10) {
setTimeout(function(){clickByItself(times);}, 1000);
}
}
An example with console logs
https://jsfiddle.net/pfsrLwh3/
The problem is that the for loop calls the setTimeout 10 times very quickly. If you want to wait until the previous function call finishes prior to calling the next, then you should use recursion or just use a setInterval.
Recursion:
function clickByItself(numIterations) {
let random = Math.floor(Math.random() * arr.length)
let i;
$(arr[random]).click();
if( numIterations < 10 ){
setTimeout(() => {
clickByItself(numIterations += 1)
}, 1000)
}
}
clickByItself(0);
With setInterval
let numIterations = 0;
function clickByItself() {
let random = Math.floor(Math.random() * arr.length);
let i;
$(arr[random]).click();
numIterations += 1;
if( numIterations > 10) {
clearInterval(loop)
}
}
let loop = setInterval(test2, 1000);
Are you saying this is working for only 4 times but I think your above code will run in an infinite loop as you are calling clickByItself() again in the for loop.
If you want press a random button by 10 times one-by-one with one second of interval from each click then replace the for loop with
for (i = 0; i < 10; i++) {
setTimeout($(arr[random]).click(), 1000);
}
I am trying to make a counter that counts from 10 to 0 using JavaScript with a loop function and setInterval but this does not work for me:
function count() {
var i;
for (i = numbers.textContent; 0 <= i; i--) {
numbers.textContent = i;
}
}
setInterval(count, 1000);
<div id="countDown">10</div>
You are doing a for loop inside setInterval
var numbers = document.getElementById('countDown');
function count() {
var i;
if(numbers.textContent>0)
numbers.textContent=numbers.textContent-1;
else
clearInterval(handle);
/*for(i=numbers.textContent; 0<=i; i--){
console.log(i)
numbers.textContent= i;
}*/
}
var handle= setInterval(count, 1000);
<div id="countDown">10</div>
This should work:
parseInt(numbers.textContent)
And there are many more:
You need a global variable.
You don't need a for loop for this.
Change the condition.
<div id="countDown">10</div>
<script>
var numbers = document.getElementById('countDown');
var interval = setInterval(count, 1000);
function count() {
var count = parseInt(numbers.textContent);
count--;
if (count == 0) {
clearInterval(interval);
}
numbers.textContent = count;
}
</script>
If you want to see it by loops, you can do using setTimeout:
<div id="countDown">10</div>
<script>
var numbers = document.getElementById('countDown');
function count() {
var count = parseInt(numbers.textContent);
count--;
numbers.textContent = count;
}
for (var i = 1; i <= parseInt(numbers.textContent); i++)
setTimeout(count, 1000 * i);
</script>
the first time count is called, the for loop will run till numbers.textContent is 0(and it's so fast that your eyes just missed that change on the page), and the 2nd call, 3rd call is just iterate around 0, nothing is changed.
BTW, after your counting is finished(or maybe you should give it a stop condition, reference to the DOC), you should unregister the interval, cause it never end by default.
I have a simple setInterval function that is done inside of a for loop. My goal is that I want the function to run on each position in the array, and once it reaches the end, I want it to stop. However, this is not happening. The timeout function is continuing to run infinitely. Can anyone explain where I'm going wrong and what I need to do to fix this?
JS
Keyhole.bufferArray = [Keyhole.twoMileBuffer, Keyhole.fiveMileBuffer, Keyhole.tenMileBuffer, Keyhole.twentyFiveMileBuffer];
var ticker = -1;
for(var i = 0; i < Keyhole.bufferArray.length; i++){
var populateServices = setInterval(function(){
++ticker;
addBuffersToService(Keyhole, i);
if(ticker >= Keyhole.bufferArray.length - 1){
ticker = -1;
clearInterval(populateServices);
}
}, 1000)
}
function addBuffersToService(Keyhole, index){
console.log(Keyhole);
}
Because you have a for loop that is making an interval for every index of the array. You should not be using the for loop if you are looping over the array with the interval. Remove the for loop.
The problem is that you overwrite your interval handler in loop. I suggest you to kepp handlers in array and remove them according to iterator varialble:
var ticker = -1;
var populateServices = [];
for(var i = 0; i < Keyhole.bufferArray.length; i++){
populateServices[ticker + 1] = setInterval(function(){
...
clearInterval(populateServices[ticker + 1]);
ticker = -1;
Note that array identifiers should be positive numbers so you should add +1 inside handlers array.
And don't forget to set ticker to -1 after clearInterval invokation.
I want to cycle through an array and display each element individually, and then remove it. Sort of like this fiddle, but I don't want it to go forever.
I tried using jQuery because I thought it would be easier, but I am clearly missing something. Can anyone help?
Here is my attempt, but it just goes straight to the last element in the array.
var list = [1,2,3,4,5,6];
var length = list.length;
for(i = 0; i < length; i++) {
$('#nums').html(list[i]).delay(750);
}
Oh, and I don't care if it's jQuery or vanilla JavaScript. Either is fine by me.
$(document).ready(function(){
var list = [1,2,3,4,5,6];
var length = list.length;
var i = 0;
var ivl = setInterval( function () {
if (i < length) {
$('#nums').html(list[i]).delay(750);
i++;
}
else {
clearInterval(ivl);
}
}, 750);
});
The (pretty clever) example uses the fact that the modulus operator (%) gives you remainder, which is periodic, so you can use it to cycle through your array by taking the remainder of an infinitely increasing number divided by the length of your list.
If you want it to stop, however, you can just do a check to see if you've finished cycling through the list:
var list = [1, 2, 3, 4, 5, 6];
var length = list.length;
var i = 0;
var finished = false;
function repeat() {
if (!finished) {
document.getElementById('nums').innerHTML = list[i % length];
i++;
if (i === length) {
finished = true;
}
} else {
clearInterval(interval);
}
}
var interval = setInterval(repeat, 750);
<div id="nums"></div>
Late to the party but wouldn't it be better to use setTimeout rather than setInterval just in case the code executed on each iteration takes longer than the interval duration? I mean, I know it's not an issue in this instance but it's just a better/safer way to do this sort of thing.
$(document).ready(function(){
var list = [1,2,3,4,5,6];
var length = list.length;
var i = 0;
(function next(){
if (i < length){
$('#nums').html(list[i++]);
setTimeout(next,750);
}
})();
});
http://jsfiddle.net/zLexhdfp/3/