I'm working on a jQuery system for an accordion-like slide show, the problem is when i try to create the auto slide for this , i have:
for (i=1;i<=5;i++) { setInterval(acordeon(i),2000) }
With this i call inside the loop the function acordeon(i) to be executed each 2000 ms, the problem is it doesn't execute all
The function parameter is the id of the div to show, for example if I have 5 divs to animate I just need to call this function with the right id and it animates just fine, the problem comes when I try to animate this: I need to execute first acordeon(1) then acordeon(2) ..... 3 , 4 and finally acordeon(5)
I tried different methods but it only works when I generate random integers and call setInterval
Ok thankĀ“s for all i hope - sure - :) you can help me , Regards
Your problem may be you are setting those intervals "all together" in like some milliseconds, thus all 5 intervals end at the "same time". Try with:
var divToAnimate = 1;
setInterval(function(){
acordeon(divToAnimate);
divToAnimate = (divToAnimate%5)+1;
},2000);
This way you'll call accordeon each 2 seconds with a different i to animate to and then increment it but keeping it in the range 1-5
here's a jFiddle
You need to pass a callback to setInterval, instead you are passing the return value of the accordion function. Try this in your for loop:
setInterval( function(){ acordeon(i) }, 2000 )
Use jQuery .each() function:
$(div).each(function(){ setInterval(acordeon($(this)),2000)});
This worked quite well for me:
for (var i = 1; i < 10; i++) {
$('#bullet-' + i).delay(i * 1000 - 1000).fadeIn('fast', function () {
var id = this
setTimeout (function () {$(id).css('color', 'lightgray');}, 1500);
});
}
Related
So far I have a little script that detects the scroll top position and at a set level I want it to trigger a jquery counter. So far I have an array with the maximum number inside var = eightyS = [3]; then there is..
if (y > 630) {
$('.targetS').each(function() {
//counter
delay(1000);
});
} else {
return false;
}
Now I've made something similar in C++ years ago (couldn't do it now with a gun to my head) so I followed a similar logic. But this is where I'm stuck. The idea behind this function is that it will do a read out on screen of 0 then 1 then 2 then 3. Any help is greatly appreciated
You could use a setInterval() which executes a function ever second such as below:
var count = 0;
var interval = setInterval(function(){
count++;
$('#counter').text(count);
}, 1000);
I've created a quick JSFiddle
You should be able to wrap this in to your code fairly easily. You may also want to use clearInterval(interval) to stop the function executing when you scroll back up the page; or when you get in to your else block, which would have the same effect. I've added a clearInterval() example to the JSFiddle on click of the stop link. You'll need to make sure the interval variable is in scope when clearing it.
I am trying to call a function from within a loop in a way that when the function finishes executing, the loop continues to the next iteration and calls it again. But instead the loop doesn't wait for the function to finish and instead calls 4 instances of the function and runs them at the same time! Should I put the whole function in the loop or is there to make the loop wait for the function to be executed? Thanks
for (var i=2; i<=4; i++){
galleryAnimation(i); //This is executed 3 times at once
}
function galleryAnimation(i){
$("#pic" + i).delay(delayTime).fadeIn(duration);
}
The function is being executed 3 times just like you requested, the problem is that both delay and fadeIn use timers: they set a timer in the future when the function will be executed and return immediately: they are non-blocking calls. So, in your case, because you're calling the function 3 times at, let's say, 0.0001s, 0.0002s, and 0.0003s, the three kick in at, let's say, 5.0001, 5.0002 and 5.0003.
What you had in mind were blocking calls to these functions. You expected the whole execution to stop until the animations were finished. This would stop the whole browser Javascript engine for the duration, meaning no other animation or user javascript interaction would be possible.
To solve it, you have to use callbacks. You can supply a function to fadeIn that will be called once the animation has completed:
http://api.jquery.com/fadeIn/
You can use queues to simulate the same on delay():
Callback to .delay()
Simplistic solution: Increase the timeout by a factor every time.
var i, factor,
duration = 250,
delayTime = 500;
for (i = 2, factor = 0; i <= 4; i++, factor++) {
galleryAnimation(i, factor);
}
function galleryAnimation(i, factor) {
$("#pic" + i).delay(factor * delayTime).fadeIn(duration);
}
This runs the same way your approach does, only the delays get longer every time.
Generic solution 1 - work with setInterval() to have your worker function (the one that does the fadeIn) called in predefined intervals:
var elements = $("#pic2,#pic3,#pic4").toArray(), // or any other way to select your elements
duration = 250,
delayTime = 500,
intervalId = setInterval(function () {
$(elements.shift()).fadeIn(duration);
if (elements.length === 0) {
clearInterval(intervalId);
}
}, delayTime);
Generic solution 2 - work with callbacks that are called when the previous animation finishes:
var elements = $("#pic2,#pic3,#pic4").toArray(), // or any other way to select your elements
duration = 250,
delayTime = 500,
next = function () {
$(elements.shift()).delay(delayTime).fadeIn(duration, next);
};
next(); // start the chain
one thing you can do, is to use an identifier (boolean) and then, in the loop, you test the identifier to decide if the loop can continue or stop.
For example,
function galleryAnimation(i, iBool){
$("#pic" + i).delay(delayTime).fadeIn(duration);
iBool = 0;
}
Then on the return;
for (var i=2; i<=4; i++){
galleryAnimation(i, iBool);
// If iBool = 0 then continue
// Else Break
}
that might be a solution, as the loop will need the returning value to determine the next step, to continue or break.
I came with my own solution that seemed to work perfectly, this is my code:
function fadeInAnimation(index){
$("#pic" + index).delay(delayTime).fadeIn(duration, function(){
photoIndex();
});
}
function photoIndex(){
index++;
fadeInAnimation(index);
}
fadeInAnimation(index);
});
I have realized that using loops is a really bad idea with things like this. This code will allow me to add as many images as I want just by renaming them in the folder rather than coding them in manually as callbacks for each photo.
Thanks for those who answered. Your suggestions are great and will definitely remember them in other applications like this one
I'm learning javascript for fun, and am having a weird problem. I'm trying to create my own fade-in function. However, my code doesn't work, it simply shows the "content" div in full opacity.
The setContentOpacity function does work, I've tested it by itself and it works like a charm.
Ideally what I think should be happening is that 1000 "setTimeout" calls should be placed on the "stack", with the first one setting opacity low with no timeout, the second one setting opacity a little higher with a small timeout, all the way to the last call which sets opacity to 1000 with 3000 timout.
So basically, it should be setting opacity to 0 right away, to ~333 in 1 second, to ~666 in 2 seconds, and to 1000 in 3 seconds. I think my logic is sound here; the calls to setting opacity should resolve in a manner over time that creates a fade in effect.
So here's the relevent code:
<script language='JavaScript' type='text/JavaScript'>
//takes a value from 0-1000
function setContentOpacity(value) {
document.getElementById('content').style.opacity = value/1000;
document.getElementById('content').style.filter = 'alpha(opacity=' + value/10 + ')';
}
function fadeInContent(){
setContentOpacity(0);
for (var i=0;i<=1000;i++)
{
setTimeout(function(){setContentOpacity(i);}, (i*3));
}
}
onload=fadeInContent;
</script>
(note: I tried calling simply setTimeout(setContentOpacity(i), (i*3));, but it didn't seem to work, and I got slightly better results using the anonymous function)
Any idea what's wrong here? Thanks in advance!
You need to capture the value of i when assigning to setTimeout.
Try this
for (var i=0;i<=1000;i++)
{
(function(ind) {
setTimeout(function(){setContentOpacity(ind);}, (ind*3));
})(i);
}
As you know the scope of a variable is function scoped. And the same value of i is shared by all the callbacks of setTimeout. So the value of i will be 1000 . So looks as if it had no effect, this is because the value of the variable scoped will always be the last iteration as it is shared by the same common scope. . By enclosing it in Immediately Invoked Function Expression you are creating a new function with the value of i scoped to it.
Check Fiddle
I think the major issue here is that you're creating a 1000 setTimeout callbacks. An alternative, if you wanted to run something every x seconds would be setInterval.
var i = 0;
var refreshIntervalId = window.setInterval(function(){
setContentOpacity( i * 3 );
i++;
if( i > 1000 ) {
clearInterval( refreshIntervalId );
}
}, 1000);
It will run once a second (1000ms), calling your opacity function each time until it hits a 1000, then turns off again.
I've background image and by using small javascript code, it moves from right to left.
HTML code
<div id="clouds_image"></div>
Javascript code
var g=0;
var speed=30;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
scroller=setTimeout(function(){rollClouds()},speed);
}
window.addEventListener?
window.addEventListener('load',rollClouds,false):
window.attachEvent('onload',rollClouds);
But i've noticed that, with time my PC CPU memory usage increased ! causing overload on my pc and if i disabled that javascript code, it back to normal.
My question
so i think i need to modify this javascript code that it not keep working forever, i mean, i want to make it to repeat that action only 5 times then stop , maybe i need to define value of g but i'm not good in javascript so any help ~ Thanks.
You need to use a variable to count how many times that function was executed, and use setInterval instead of setTimeout: See example
http://jsfiddle.net/EQDjx/206/ (my counter start from 100 and goes down to 0)
for a more nice effect i recomand you to use jquery. See animate function
http://api.jquery.com/animate/
var g = 1000;
var speed=300;
var counter = 100;
function rollClouds() {
document.getElementById('clouds_image').style.backgroundPosition=g+'px 0';
g--;
if (counter < 1) clearInterval(interval);
}
interval = setInterval(function(){rollClouds()}, speed)
A cleaner solution might be to use jQuery to move the background:
function moveClouds() {
$("#clouds_image").css({left:"-2000px"});
$("#clouds_image").animate({left:"2000px"},10000);
}
Then you might set an interval to trigger it every x milliseconds.
setInterval(moveClouds,10000)
JSFiddle is here: http://jsfiddle.net/qXpVX/
Scenario:
I want to create a jQuery controllable jackpot "spinner" that will rapidly sequence a number of random images through a div before settling on one, with the delay interval between each equal but changeable. For mockup purposes, I'm simply changing CSS color classes to a box, although in the final I'll use background images.
I thought this would be a no-brainer to do with a loop. I'm sure there's a more efficient way to do this, but guessed the below would work fine. However, I discovered I have no way to control the CSS color swap speed. This whips through the color class changes instantly and just shows the last one. What I'd like is a delay where indicated.
jQuery delay() doesn't seem to work when chained with addClass(), though it works fine with effects. So I tried using window.setTimeout, but as far as I can see, in this context it requires a kludgey function call. The code as written below executes all the function calls after the loop has run. Is this a closure issue? Don't want to use setInterval because these will be limited iterations.
Thanks for any advice!
for (var j= 9; j >= 0; j--) {
$('#box1').attr('class', 'boxes'); // strips all current classes, replaces them with class 'boxes', which has general CSS characteristics
var numRand = Math.floor(Math.random() * 6);
var randomClass = colorArray1[numRand]; // pull random class from an array of six choices
$('#box1').addClass(randomClass);
// Everything above here works fine, would like loop delay here
// Tried using straight-up setTimeout -- doesn't appear to like loops
window.setTimeout(outerFunc, 1000);
};
function outerFunc() {
alert('nobody here but us chickens!');
};
If you want to use .delay() with a method like .addClass(), you can add it to the queue with jQuery's .queue() method.
$('#box1').delay(1000)
.queue(function( nxt ) {
$(this).addClass(randomClass);
nxt(); // allow the queue to continue
});
Otherwise, if I get what you want, you could multiply the 1000 ms for the setTimeout() by the current value of j, so that each time the duration increases.
window.setTimeout(outerFunc, (1000 * j));
setTimeout and setInterval work differently in javascript to the way you want to use them.
Both functions take the function that you pass in and attach them to the window DOM object. Then, after the delay you have passed in has passed, and when there is no other script currently running, they get called from the window object.
To get the functionality you are after, you will need to convert your code so that the jQuery addclass call is inside the function you are passing to setTimeout.
Perhaps recursion would work?
// this code is not tested
var j = 9;
function myFunc() {
// code here
j--;
if(j >= 0) setInterval(myFunc, 1000);
}
I haven't used the queue class in jQuery myself (first I've heard of it, but it sounds cool). That might be the better answer, but this should be a decent alternative if the queue doesn't work as expected.
UPDATE: I just noticed that in your code it looks like you are expecting setTimeout to work like Thread.Sleep in .Net. setTimeout doesn't work that way. It works more like Thread.Start where your code continues on as soon as you call it.