How create a chained delayed animation sequence in jQuery? - javascript

Consider having the following objects:
<div id="d1"><span>This is div1</span></div>
<div id="d2"><span>This is div2</span></div>
<div id="d3"><span>This is div3</span></div>
<div id="d4"><span>This is div4</span></div>
<div id="clickhere"><span>Start animation</span></div>
And consider that I would like to apply, using jQuery, an animation on each of the four element listed before.
What I have now
Consider the following code applied in the head section if the page:
function start_anim() {
$("#d1").animate({top:"-50px"},1000,function(){}); // Animating div1
$("#d2").animate({top:"-50px"},1000,function(){}); // Animating div2
$("#d3").animate({top:"-50px"},1000,function(){}); // Animating div3
$("#d4").animate({top:"-50px"},1000,function(){}); // Animating div4
}
$(document).ready($('#clickhere').click(start_anim));
This fragment of script will cause a synchronous translation of the four divs when the event click is fired.
What I would like to have
However I would like to have the first div move first, then I would like to have the second div move when the first div's animation has reached the 50%. The same for the third and the last div.
How can I reach this? Thankyou

Something like:
$("#d1").animate({top:-50}, 1000);
$("#d2").delay(500).animate({top:-50}, 1000);
$("#d3").delay(1000).animate({top:-50}, 1000);
$("#d4").delay(1500).animate({top:-50}, 1000);
Or even better:
var duration = 1000;
$('#d1,#d2,#d3,#d4').each(function(i) {
$(this).delay( i*(duration/2) ).animate({top:-50}, duration);
});

Related

How to apply animations on two elements at once with animated.css

I am working on a simple slideshow where each slide has its own duration.
I would like to add transitions between the slides using animate.css by adding and removing classes on the current and the next slides.
My problem is that - with my current approach - only the next slide will be animated (it slides in) but the current one is just disappear without any animation.
I have tried to detect the end of the current animation and then change(adding/removing) the classes but in that case there was a huge gap between the slides...
How can make sure that two animations plays at once?`
var slides = $this.find('.slide');
slideIt = function(time) {
setTimeout(function() {
var duration = slides.eq(nextSlide).data('duration');
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut)
.hide();
slides.eq(nextSlide)
.removeClass(animateOut)
.addClass(animateIn)
.show();
slideIt(duration);
currentSlide = nextSlide; nextSlide ++;
if (nextSlide == slidesLength) { nextSlide = 0;}
},time);
};
Thank you for the help in advance!
Ps.: While typing this post I have realized that it must be the .hide() but without it only the first slide displayed.
Native CSS animations on two different elements should always run at the same time.
But if you hide an element, it disappears before the animation has even started. You have to add a timer for that.
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut);
// save the jQuery instance of the element that should be hidden.
var $currentSlide = slides.eq(currentSlide);
// hide this element later
setTimeout(function() {
$currentSlide.hide();
}, 1000); // 1000 for 1000ms, replace that with the duration of the animateOut animation
If my first answer doesn't satisfy you, because you want so solve that on the CSS side, when there is a second way:
Remove the .hide() in JavaScript.
Make sure your CSS animation ends with a state, there the element cannot be seen anymore (like transform: scale(0) or left: -100%).
Maintain that final state of the CSS animation. To do that, see: Maintaining the final state at end of a CSS3 animation

Why is my jquery div slider skipping some of the divs?

http://jsfiddle.net/czt0mycw/
<body>
<div id="hold_divs">hold divs
<div id="div1">div1</div>
<div id="div2">div2</div>
<div id="div3">div3</div>
<div id="div4">div4</div>
</div>
</body>
This is my first time building a jquery slider and it is exhibiting the strangest behavior. When the page first loads, it slides(automatically) the contents(my 4 divs stacked on top of one another) to the right successfully. But after a full slide show is completed, the slider no longer displays div1(the div with the red background). Instead, it skips(I believe that's whats happening) and shows the parent div("hold_divs").
When I was debugging, I altered the code to slide in only 2 divs, and a similar error occurred. This time, the two divs slid correctly only once (when the page is first loaded). After the first slide show completed successfully, it displayed the first of the 2 divs, but the 2nd div in the was not displayed; the 3rd div in the array was. O.o
http://jsfiddle.net/czt0mycw/1/
You need to reset the divs on the next iteration of the interval. Change:
setInterval(function()
{
var divs=[$("#div4"),$("#div3"),$("#div2"),$("#div1")];
var width=divs[x].width();
divs[x].stop().animate({right:"100%"},"slow");
x+=1;
if(x==4)
{
$("#div4,#div3,#div2,#div1").css("right",0);
x=0;
}
},3000);
to
setInterval(function()
{
if(x==4)
{
$("#div4,#div3,#div2,#div1").css("right",0);
x=0;
return;
}
var divs=[$("#div4"),$("#div3"),$("#div2"),$("#div1")];
var width=divs[x].width();
divs[x].stop().animate({right:"100%"},"slow");
x+=1;
},3000);
What's happening is that you're resetting the divs immediately after you start the animation for the 4th div. Instead, you want to reset the divs immediately before you start the animation again for the 1st div.

Javascript setInterval taking too long to reset

Hey I have a panel (br_Panel) that contains four divs with the class 'smallPanel' and id br_Panel1, br_Panel2, etc that are of the same and equal size and positioned overlapping each other. When the function runs, every 5 seconds one fades out and shows the one below, and when they have all faded out they all come back with the fadeIn. The problem is the pause between the last div's fadeout and the fadein for all of them is 15 seconds, three times as long as it takes each div to leave. How can I reduce this pause in reset time to 5 seconds?
setInterval(function() {
if(i < 0) {
$('#br_Panel').find($('.smallPanel')).fadeIn();
i = 5;
}
else
i--;
$('#br_Panel').find($('#br_Panel' + i)).fadeOut();
}, 5000);
This is the html (if it helps, each of the innermost divs is positioned absolute to #br_Panel so that they overlap each other):
<div class="height1 panel" id="br_Panel">
<div class="smallPanel" id="br_Panel1">content</div>
<div class="smallPanel" id="br_Panel2">content</div>
<div class="smallPanel" id="br_Panel3">content</div>
<div class="smallPanel" id="br_Panel4">content</div>
</div>
You mentioned that your br_Panel contains four divs with the class smallPanel, but your interval function will run six times before i is reset (5, 4, 3, 2, 1, 0). It may be that your function is running 2 more times than needed, which causes your delay to be 10 seconds longer than it should be.
As an additional note, when using .find(), you need only pass in the string css selector you are using, not the enter jQuery object:
$('#br_Panel').find('.smallPanel').fadeIn();

Fading a <div> With 'onmouseover' and 'onmouseout' Happens Several Times

I have a <div> on my web page that I would like to have an opacity of 1 while you're hovering over it, but when the mouse is not hovering over it I would like it to fade to an opacity of 0.3. My problem is that currently when I hover over the <div> it starts fading in and out several times (rather than just once). I'm not sure if this is why, but I suspect it's because it detects the mouse rolling over the multiple <div>s that are within the one that I set to fade out.
Here is a very simplified segment of my web page to illustrate what I have so far:
<div id="div1">
<div id="div2" onmouseover="fadeElementTo('div1', 500, 1)" onmouseout="fadeElementTo('div1', 500, 0.3)">
<div id="div3">
<div id="div4">
</div>
</div>
<button id="myButton" onclick="doACoolAnimation()" ></button>
</div>
</div>
My fadeElementTo() function is pretty simple:
function fadeElementTo(eid, speed, opacity, callback) {
$("#" + eid).fadeTo(speed, opacity, callback);
}
In case it's relevant, I also have a button that animates the same div by simply moving it left or right when the button is clicked.
function doACoolAnimation() {
var hiddenState = GLOBAL_VAR.hiddenState;
// If the <div> is already hidden, make it visible
if (hiddenState == null || hiddenState == 1) {
GLOBAL_VAR.hiddenState = 0;
$("#div1").animate({
left: "0px"
}, 1500);
}
// Otherwise, hide it
else {
GLOBAL_VAR.hiddenState = 1;
$("#div1").animate({
left: "-800px"
}, 1500);
}
}
Any ideas what might be causing my bug? And better yet, what can I do to fix it?
Try onmouseenter instead of onmouseover and use jQuery to attach/bind those events rather than the attributes so it works the same across all browsers.
$('#outer').mouseenter(function() {
$('#log').append('<div>Handler for .mouseenter() called.</div>');
});
see here
Use mouseenter event to stop event bubbling, and stop method to make sure you clear unfinished animations on that element.
$('#div2').mouseenter(function(){
$('#div1').stop().fadeTo(500,1);
});
It detects the events multiple times. For example, if you want to change the size, going on and off fast changes the size even when the mouse is not on the div. The code needs to exit the program when the mouse is not on the div. To do that, you might include the code in something that kills the code when the mouse is not on top of the div so that the queued fades/animations do not run.
Edit:
Try looking at the JQuery documentation to see if there is anything that you can use.
You might able to use these:

Div is jumpy with fadeIn jQuery

When I roll over .comptext_rollover div it should hide the initial div on the page and show the minipage div. but it does but is sometimes really jumpy and also the minipage div sometimes shows below the initialpage div. any ideas? sorry i am new to coding! Thanks in advance.
$(document).ready(function() {
$('#mini_page').hide();
$('.comptext_rollover').hover(function() {
$('#initial_page').hide();
$('.register_button').hide();
$('#mini_page').fadeIn(100);
$('#container').css({
'margin-top': '-217px'
});
}, function() {
$('#mini_page').hide();
$('#initial_page').show();
$('.register_button').show();
$('#container').css({
'margin-top': '-150px'
});
});
});
I prepared a fiddle demo HERE
re-EDIT:
JSFIDDLE DEMO
(the demo may be incorrect while the main CSS is an external link)
I used:
<div id="container">
<div id="initial_page" class="page">
<div id="playvideo_hoverbutton"></div>
<div class="register_button"></div>
<div id="invisible_register2"></div>
<div id="termsandconditionsapplyshort"></div>
</div>
<div id="mini_page" class="page">
<div id="minicar_animated"></div>
<div id="worth25k"></div>
<div class="register_button"></div>
<div id="invisible_register"></div>
</div>
<!-- THE ROLLOVER IS OUT OF ALL 'PAGES'! -->
<div class="comptext_rollover">
<!--<div id="competition_text"></div>-->
</div>
</div>
$('#mini_page').hide();
$('.comptext_rollover').mouseenter(function() {
$('.page').fadeToggle(400);
});
$('.comptext_rollover').mouseleave(function() {
$('.page').fadeToggle(400);
});
In any case what you should do:
Position absolute the 2 screens you need to 'swap' into a container.
Than what you do:
Position the 'rollover' element outside the 'screens'.
Adjust the marginTop of the bigger image(car image) in the CSS (like I did) to fix the buggy 'jumps'.
IF POSSIBLE: ONLY ONE rollover ACTION ELEMENT!
Fix the margin-top of the car image. (give it a -Npx)
Doing so you don't need to do that stuff with positioning your container -Npx
There is also a simpler way to do the same effect:
you add to BOTH screens a class .swappable, making the second one (CSS)display:none; , and than you just use jQuery toggling just this class.
you've not set a great deal of time for the fade in. you're also just hiding some of the divs which makes the fade in move around depending on where you put them. maybe use slides instead. I have saved an example here: http://jsfiddle.net/kBEUH/
$(document).ready(function(){
$('#mini_page').hide();
$('.comptext_rollover').hover(function () {
$('#initial_page').fadeOut(1000);
$('.register_button').fadeOut(1000);
$('#mini_page').slideDown(1000);
}, function(){
$('#mini_page').slideUp(1000);
$('#initial_page').fadeIn(1000);
$('.register_button').fadeIn(1000);
});
});
if you put a console.log in your hover() function, you'll see hover is firing like crazy. This causes the animation to start over and over again, while moving your mouse.
You could take advantage of the jquery :animated selector:
$('.comptext_rollover').hover(function() {
//enable this line to see the hover event is firing every time your mouse moves
//console.log("hovering")
//if the div is in the middle of an animation, do nothing
if (!$("#mini_page").is(":animated")) {
$('#initial_page').hide();
$('.register_button').hide();
$('#mini_page').fadeIn(100);
$('#container').css({
'margin-top': '-217px'
});
}
}, function() {
//etc
});
EDIT:
Now I think of it, your probably want to use .mouseenter() and .mouseleave() instead of hover()
$('.comptext_rollover').mouseenter(function() {
//your code
}).mouseleave(function() {
//your code
});

Categories