How to fadeIn and fadeOut in sequence - javascript

I want fadeIn and fadeOut effect on div one by one sequentially with regular interval. I tried with following code but it will all div at a time fadeIn and fadeOut.
HTML
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
jQuery
function fade()
{
$("div").each(function(){
$(this).fadeOut(3000);
});
$("div").each(function(){
$(this).fadeIn(3000);
});
}
setInterval(fade,6000);
Update
I want First of all div one by one disappear from screen. When all div disappear then one by one show. This should happen regular interval.
JS Fiddle

There are different ways to execute deferred actions sequentially. Here is a good article about this http://www.paulirish.com/2008/sequentially-chain-your-callbacks-in-jquery-two-ways/
According to the comments and your later defined needs, you can solve it like this and use fadeTo instead of fadeIn/fadeOut
var start = $('div:first');
function fade(lobj){
lobj.fadeTo('slow',lobj.css('opacity')==1 ? 0 : 1,function(){
var nobj = lobj.next();
if(nobj.length)
fade(nobj);
else
fade(start);
});
}
fade(start);
http://jsfiddle.net/sofl/1n30hp49/15/

I guess you should use the function next on jQuery, like this, I just wrote forking in your snippet on jsfiddle:
http://jsfiddle.net/1n30hp49/17/
In this code above I also used the $el to define who is going to be the next element:
function fade( el, timer ){
el.fadeOut( timer , function() {
$( this ).fadeIn( timer , function() {
fade( $( this ).next(), timer ) ;
} ) ;
} ) ;
}
var timer = 1000 ;
//run function
fade( $( "div:first-child" ), 1000 ) ;
try to do this, if so, let me know if it works! att.

A reliable way to do this would be to use jQuery animation queues and a deferred object in a recursive loop. The advantage of this method is the ease you can add animations into the fade function. It is also much easier to read than a bunch of nested callbacks.
// Get all the div elements
var divs = $('div');
/**
* Fade in a specific indexed div element
* #param {integer} i
* #return {object} $.promise
*/
function fade(i)
{
return divs.eq(i)
.fadeIn(3000)
.delay(6000)
.fadeOut(3000)
.promise();
}
/**
* Recursive sequence runner
* #param {integer} i
*/
function runSequence(i) {
// If i is null/false set it to 0
i = ! i ? 0 : i;
// Run animation on item i
var promise = fade(i);
// Use the promise to queue up the next item
// by calling this function again when the
// animation is complete
promise.then(function() {
if (i > divs.length) {
i = 0;
}
runSequence(++i);
});
}
// Run the sequence for the first time
runSequence();
JSFiddle example

There's been some great answers here but just to add to the diversity, here's another way with just good-ol' Fade in's and outs:
PLEASE NOTE
Stackoverflow's method of including third party scripts in their snippets interferes with this example so I had to add a container div around the other divs. For a purer example see the fiddle.
function fade() {
var thisObj = this;
thisObj.out = function(el, timer) {
el.fadeOut( timer , function() {
if ($( this ).prev().length > 0) {
thisObj.out( $( this ).prev(), timer );
} else {
thisObj.in( $( "#container").find("div:first-child" ), timer );
}
} ) ;
}
thisObj.in = function(el, timer) {
el.fadeIn( timer , function() {
if ($( this ).next().length > 0) {
thisObj.in( $( this ).next(), timer ) ;
} else {
thisObj.out( $( "#container").find("div:last-child" ), timer );
}
} );
}
}
new fade().out( $( "#container").find("div:last-child" ), 1000 );
#container div {
background : #00f;
height: 50px;
width : 50px;
margin : 5px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
To change the order of the fade in and out, just change last-child to first-child.

Related

Execute jQuery function after first is complete

I have created a page where I have multiple functionality done but stuck with timing of it, if you see the page example here in JSFiddle.
When you open the page, it will first run a loader and when the loader is complete there are multiple boxes, which is showing one by one but in currently its not happening, Loader is loading fine and then in the next step where centered columns has to appear one by one, the first four columns loads by default and then other div loads one by one.
My question is, how can I execute a function and execute another another function once the previous is complete.
For loader I have the following:
//--------- process bar animation
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
}
var width = 100,
perfData = window.performance.timing, // The PerformanceTiming interface represents timing-related performance information for the given page.
EstimatedTime = -(perfData.loadEventEnd - perfData.navigationStart),
time = parseInt((EstimatedTime/1000)%60)*100;
showText("#msg", "Welcome to the Company Group", 0, width);
// Loadbar Animation
$(".loadbar").animate({
width: width + "%"
}, time);
// Loadbar Glow Animation
$(".glow").animate({
width: width + "%"
}, time);
// Percentage Increment Animation
var PercentageID = $("#precent"),
start = 0,
end = 100,
durataion = time;
animateValue(PercentageID, start, end, durataion);
function animateValue(id, start, end, duration) {
var range = end - start,
current = start,
increment = end > start? 1 : -1,
stepTime = Math.abs(Math.floor(duration / range)),
obj = $(id);
var timer = setInterval(function() {
current += increment;
$(obj).text(current + "%");
//obj.innerHTML = current;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}
// Fading Out Loadbar on Finised
setTimeout(function(){
$('.preloader-wrap').fadeOut(300);
$('.loader-wrap').fadeOut(300);
$('.main-wrapper').fadeIn(300);
$('body').addClass('bg');
}, time);
For showing div one by one in next step I have the following code:
$(".column-wrapper").each(function(index) {
var $this = $(this);
setTimeout(function () { $this.addClass("show"); }, index * 1000);
});
I use trigger and on for those kind of things. You had a lot of code, so sorry, I didn't want to read all of that but this is a simplified example.
https://jsfiddle.net/2d6p4L6k/1/
$(document).ready(function(){
var action = function(){
$('div.one').css('background-color', 'green');
/* do whatever you want to do */
/* then trigger(call) another function */
$(document).trigger('hello-action');
};
var hello = function() {
$('div.two').css('background-color', 'fuchsia');
};
/* just listen if anything triggers/calls "hello-action" */
/* if so call function named hello */
$(document).on('hello-action', hello);
setTimeout(action, 1500);
});
div {
width: 50px;
height: 50px;
background-color: orange;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="one">one</div>
<div class="two">two</div>
Note: To keep it simple we trigger and listen on $(document) which is really just to keep it simple. A better approach would be to have a wrapper element, and then you can do exactly the same (trigger and listen) just on that element and not on the entire document. You can find more details on the jQuery API .trigger()

Randomly fade in div with jQuery

Any help here is much appreciated. I would like to use jQuery to solve the following...
There are two divs. I would like to randomly fade in one of the divs (green or red), wait a few seconds, then fade it away. Then randomly fades in another one. I've tried using math.random();but I can't seem to get it working correctly.
So basically it chooses either the red or green div.. fades it away after a few seconds, randomly chooses the red or green div... then fades it away after a few seconds. And It just keeps repeating.
html:
<div id="one">This is the first block</div>
<div id="two">This is the second block</div>
css:
#one {
background: red;
width:300px;
height:100px;
}
#two {
background: green;
width:300px;
height:100px;
}
Give both divs a class name like .fade for easier to manage.
Then you can do like this:
(function randomFade() {
var fadeDivs = $('.fade'),
el = fadeDivs.eq(Math.floor(Math.random() * fadeDivs.length));
el.fadeIn('1000').delay(2000).fadeOut('1000',randomFade);
})();
Fiddle Demo
You could do this:
function fadeRandomly() {
// fade both out at first
$('#one').fadeOut(/* duration */);
$('#two').fadeOut(/* duration */);
if (Math.random() > 0.5) {
$('#one').fadeIn(/* duration */);
} else {
$('#two').fadeIn(/* duration */);
}
}
setInterval(fadeRandomly, /* duration between animations */);
This should work:
var rnd = Math.floor(Math.random() * 2) + 1;//outputs either 1 or 2
if (rnd == 1) {
$('#one').fadeIn(500).delay(500).fadeOut(500);
} else {
$('#two').fadeIn(500).delay(500).fadeOut(500);
}
Hope this helps!
something like: I added a function just in case you have more divs to deal with you and you want to expand the scope of your fades.
var a = ['one', 'two']; // the name of your divs
function fadeRandomDiv(min, max) {
var divtofade = a[Math.floor(Math.random() * (max - min + 1) + min)];
// delay 4 seconds, then fade out
jQuery( "#" + divtofade ).fadeIn( "slow" ).delay(4000).fadeOut("slow");
}
fadeRandomDiv(1, a.length - 1)
if you want to repeadedly call it.
// every 3 seconds call the function
setInterval(function(){
fadeRandomDiv(1, a.length - 1);
}, 3000);

How to make my script loop

I created an image slider that ends on one image, but now I'd like to take it a step further and make it loop.
Here is my code in the head tag
<style>
#picOne, #picTwo, #picThree, #picFour, #picFive{
position:absolute;
display: none;
}
#pics {
width:500px;
height:332px;
}
</style>
<script src="http://code.jquery.com/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
$('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFive').delay(20000).fadeIn(1500).delay(3500);
});
</script>
and here is where it is implemented in the body code
<div id="pics">
<center>
<img src="img/dolllay.jpg" width="500" height="332" id="picFive" />
<img src="img/dye.jpg" width="500" height="332" id="picTwo" />
<img src="img/dollsit.jpg" width="500" height="332" id="picThree" />
<img src="img/heirloom.jpg" width="500" height="332" id="picFour" />
<img src="img/heritage.jpg" width="500" height="332" id="picOne" />
</center>
</div>
Could I turn it into a function and then loop it? Can I get any guidance on that? Thank you very much
Everyone's answering the question, but not solving the problem.
Sure, you can just put a loop wrapper around it (preferably one that doesn't terminate), but why not just program it right? Why have all the hardcoded times, and why not make it more robust?
Try rewriting your code like this. It makes it much easier to modify the pictures you loop through:
var pictures = ["picOne", "picTwo", "picThree", "picFour", "picFive"];
var index = 0;
var displayImage = function() {
if (index == pictures.length) { return; }
$("#" + pictures[index++]).fadeIn(1500).delay(3500).fadeOut(1500, displayImage);
};
displayImage();
Then, if you want to loop back, you simply tweak the displayImage function:
var displayImage = function() {
if (index == pictures.length) { index = 0; }
$("#" + pictures[index++]).fadeIn(1500).delay(3500).fadeOut(1500, displayImage);
};
TRY IT at jsfiddle
EDIT
On more careful reading of your question, I see that my original answer didn't do exactly what you needed. You have it set so that every five seconds, one will have faded out and the other one will have faded in. Currently, mine takes 6.5 seconds, since mine is all operating sequentially instead of concurrently. To make it come close to matching yours, just change the 1500s to 750s:
$("#" + pictures[index++]).fadeIn(750).delay(3500).fadeOut(750, displayImage);
This will take the right amount of time. It's slightly different from yours, in that one fades out all the way before the other fades in. The alternative is to actually skip the fadeIn and keep the fadeout. This is a lot closer to the way yours looks.
$("#" + pictures[index++]).show().delay(3500).fadeOut(1500, displayImage);
Or, make a very small fadein, to help reduce the flash of the new image:
$("#" + pictures[index++]).fadeIn(100).delay(3500).fadeOut(1400, displayImage);
Final Edit (really!)
Ok, to get the fadeIn and fadeOut to work reliably at the same time, the solution was to use neither. I went back to using animate, instead. As a result, I had to completely rewrite the displayImage function, but this is exactly what you need:
var displayImage = function () {
if (index == pictures.length) {
index = 0;
}
$("#" + pictures[index]).show().delay(3500).animate({
opacity: 0.2
}, {
step: function (now) {
var idx = (index + 1) % pictures.length;
var val = 1.2 - now;
$("#" + pictures[idx]).show().css("opacity", val);
},
complete: function () {
$("#" + pictures[index++]).hide();
displayImage();
}
});
};
What this does is move the sequence to "show->fadeIn and Out" instead of "fade in -> show -> fade out". To make your transition smooth, I only fade it out to 0.2 instead of 0. The step function is what fades the other one in at the same time. Once the new pic is visible, I completely hide the old pic.
Here's the working fiddle for it.
$(document).ready(function() {
setInterval(example, 10000); // repeat every 10 seconds
});
function example() {
$('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
$('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFive').delay(20000).fadeIn(1500).delay(3500);
}
A better way would be to give each pic the same class such as 'fadeinout'. This will mean you don't have to re-write your code when you add/remove more pics.
eg
<img id="picFive" class="fadeinout" ....
/* not sure if they are even <img>s but whatever they are*/
Then do
$(document).ready(function() {
beginFades();
});
function beginFades() {
$('.fadeinout').each( function(i,el) { // find all elements with fadeinout
//for each one, trigger the start of the fading after i*5000 milliseconds
//i is the index of the element as it was found by jQuery - this will be in
//document order (which actually may not be what you have but I'm guessing
//it is)
setTimeout(function(){
makeImgFadeInOut($(el))
}, i*5000);
});
}
function makeImgFadeInOut(el) {
//trigger a single fadeIn, fadeOut.
//But add a callback function to the end of fadeOut which retriggers the whole
//thing
el.fadeIn(1500).delay(3500).fadeOut(1500, function(){makeImgFadeInOut(el);});
}
WORKING DEMO (WITH DIVS)
You can use setInterval to loop it forever, or setTimeout to loop it for a specific duration.
<script type="text/javascript">
$(document).ready(function() {
setInterval(ImageSlider, 1000);
});
function ImageSlider() {
$('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
$('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFive').delay(20000).fadeIn(1500).delay(3500);
}
</script>
If you want to have total control upon your elements you can use this:
var elements = [{
el: '#pic1',
delay: 3500,
fadeIn: 1500,
fadeOut: 1500
},
{
el: '#pic2',
delay: 3500,
fadeIn: 1500,
fadeOut: 1500
}
//... other elements
]
var index = null;
(function loop(){
index = index || 0;
index = index % elements.length();
$(elements[index].el).fadeIn(elements[index].fadeIn, function(){
$(this).delay(elements[index].delay)
.fadeOut(elements[index].fadeOut, function(){
index++;
window.setTimeout(loop, 5000);
});
})();
Edit : forgot to execute the first iteration of the loop function and removing the useless call for index inside the loop
The good thing about how this loop works is that it doesn't use the SetInterval function.
and the code inside the loop need to finish what it does inside before iterating again.
(you won't have this hideous bug if you click an other tab and go back to your carousel)
#ElRoconno answer is pretty good too if you require less configuration
Use any of this-
setInterval() - executes a function, over and over again, at specified time intervals
setInterval(function(){alert("Hello")},3000);
setTimeout() - executes a function, once, after waiting a specified number of milliseconds.
setTimeout(function(){alert("Hello")},3000);
What is the difference between both setInterval and setTimeout
for you may be the setTimeout will not work as it will run only once after a delay and setInterval will go on to make continuous repetitive call until the window.clearInterval(intervalVariable) is been called
I have created an example on jsfiddler here. Basically you don't have to do this one at a time. Just get the whole collection of images as an array and loop over them. Hope this helps
$(document).ready(function () {
var arr = $('.pics')
arr.hide();
$(arr[0]).fadeIn(1500).delay(3500).fadeOut(1500);
var index = 1;
var maxIndex = arr.length - 1;
setInterval(function () {
/*arr.hide();
var pic = $(arr[index]);
pic.show();
*/
var pic = $(arr[index]);
pic.fadeIn(1500).delay(3500).fadeOut(1500);
index++;
if (index >= maxIndex) {
index = 0;
}
}, 6500);
});
There's really no need for setInterval here since you can use the callback built-into .fadeOut(), nor having to enumerate an array of images. You can do something as simple as:
var idx = 0;
fade();
function fade() {
if (idx >= $('img').length) idx = 0;
$('img').eq(idx).fadeIn(1500).delay(3500).fadeOut(1500, fade);
idx++;
}
jsFiddle example

Animating long sequences in jQuery

I have to make a long animation with jQuery, full of fadeOuts,fadeIns,slideIns,...
The problem I am having is that my code looks ugly and it is full of callback. Also, if I want to stop animation for some time like: slideOut->wait 5 seconds->slideIn I have to use delay and I am not sure if that is the best practice.
Example:
/* Slides */
var slide1 = $('div#slide1'),
slide2 = $('div#slide2'),
slide3 = $('div#slide3');
$(document).ready(function(){
slide1.fadeIn(function(){
slide2.fadeIn(function(){
slide3.fadeIn().delay(3000).fadeOut(function(){
slide2.fadeOut(function(){
slide1.fadeOut();
});
});
});
});
});
JSFIddle: http://jsfiddle.net/ZPvrD/6/
Question: Is there any other way of building animations in jQuery, possibly even some great plugin to help me solve this problem?
Thanks!
Here's the plugin you were looking for :) Does the exact same thing, but is much more flexible than your existing code http://jsfiddle.net/ZPvrD/11/
(function($){
$.fn.fadeInOut = function(middleDelay) {
middleDelay = middleDelay || 0;
var index = 0,
direction = 1, // 1: fading in; -1: fading out
me = this,
size = me.size();
function nextAnimation() {
// Before the first element, we're done
if (index === -1 ) { return; }
var currentEl = $(me.get(index)),
goingForward = direction === 1,
isLastElement = index === (size - 1);
// Change direction for the next animation, don't update index
// since next frame will fade the same element out
if (isLastElement && goingForward) {
direction = -1;
} else {
index += direction;
}
// At the last element, before starting to fade out, add a delay
if ( isLastElement && !goingForward) {
currentEl.delay(middleDelay);
}
if (goingForward) {
currentEl.fadeIn(nextAnimation);
} else {
currentEl.fadeOut(nextAnimation);
}
}
nextAnimation();
return this;
}
})(jQuery);
And you call it like
$('div.slideWrapper>div.slide').fadeInOut(3000);
This process of traversing up and down a list of jQuery elements waiting for each animation to finish could be abstracted so that it could be used for other things besides fadeIn and fadeOut. I'll leave that for you to try out if you feel adventurous.
Try this:
/* Slides */
var slide = $('div[id*="slide"]');
$( function(){
slide.each( function( k ){
$( this ).delay( 500 * k ).fadeIn();
});
});
JQuery animations take two parameters (maximum), duration and complete, duration is the time in milliseconds for how long you want your animation to complete, or you can use "slow" or "fast", and the second params complete which is the callback function.
If don't want to use delay, you may make the previous animation slow.
e.g.
slide1.fadeIn(5000, function(){
slide2.fadeIn();
};

jQuery find when user scrolled out an element

I have 2 divs:
<div id="div1"></div>
<div id="div2"></div>
I would like to add css({'position':'relative'}) to div2 ONLY when a user scrolls the page and div1 is no longer visible on the page. When div1 is visible again, I want to remove the css rule.
Can anyone help me?
You could try this code:
$(window).bind('scroll', function() {
if ($(document).scrollTop() >= $('#div1').offset().top - $(window).height()) {
//Change css relative
}else{
}
});
You should play with that until you got a perfect result. Good luck
this is not perfect, but i've written you a quick plugin to take care of this:
http://jsfiddle.net/m7ztR/1/
it can be used in two ways:
it gives you a new selector
console.log( $( "#elem" ).is( ":inView" )? "visible":"invisible" );
you can also use this to get all visible elements, e.g.
console.log( $( "p:inView" ).get() );
and something like an event-listener
$( "#watchThisElement" ).visibilityChange( function( visible ){
if( visible ){
// do this ...
}
else{
// do that ...
}
} );
note: this is not complete for a bunch of reasons!!
it only handles vertical scrolling
it does not handle iframes (and might screw up horribly with nested scrolling)
there is no unbind
it might get slow if you watch a lot of elements
does not take window resizing into account
it's something i quickly hacked up from similar code i had sitting around.
if the jsfiddle link ever dies, here's the actual code and markup:
html:
<div id="status">look at my background color!</div>
<div id="above">lots of space above ... </div>
<div id="trackMe">i'm being tracked!</div>
<div id="below">lots of space below ... </div>
css:
#status{
position: fixed;
right: 0;
top: 0;
background-color: red;
}
#above, #below{
height: 800px;
background-color: yellow;
}
javascript:
/**
* jquery (in)visibility plugin ...
*/
(function( $ ){
var w = $( window );
// add a custom ":inView" selector
$.expr[':'].inView = function(obj){
var $this = $(obj);
var relY = $this.offset().top - w.scrollTop();
return relY >= 0 && relY <= w.height();
};
$.fn.visibilityChange = function( fun ) {
return this.each(function() {
var elem = $(this);
var pVisible = elem.is( ":inView" );
$( document ).scroll( function( e ){
if( pVisible != elem.is( ":inView" ) ){
pVisible = !pVisible;
fun( pVisible );
}
});
});
};
})( jQuery );
$( "#trackMe" ).visibilityChange( function( visible ){
$( "#status" ).css( "background-color", visible? "green":"red" );
} );
I think you should do some tricks with window.onscroll, the window height and the heigt of div1. As in...do some code in the onscroll method...check for the window height, check for the height of div1, do some calculations on it and check if the div is out of sight...if true...remove the css.

Categories