Why is my jquery animate() callback causing an overflow ? Recursion - javascript

I am using a recursive callback with the animate() jquery function.
However the page crashes everytime from the start.
var goingDown = true;
function animateChevron() {
if (goingDown) {
goingDown = !goingDown;
$('#chevron').animate({'opacity': 1}, 500, animateChevron);
}
else {
goingDown = !goingDown;
$('#chevron').animate({'opacity': 0.1}, 500, animateChevron);
}
}
$(document).ready(function(){
animateChevron();
});
Thank you
EDIT: I want it to act in a loop: the chevron appears, then disappears, then appears again etc. As long as the user is on the page.

Try this
$('#chevron').animate({'opacity': 1}, {
duration: 500,
complete: animateChevron
});
Also you can make this better
function animateChevron() {
$('#chevron').animate({'opacity': 1}, {
duration: 500
}).animate({'opacity': 0.1}, {
duration: 500,
complete: animateChevron
});
}

Please try this
$(document).ready(function(){
var speed=500; //in micro seconds
setInterval(function(){
var opacity=$('#chevron').css('opacity')<1 ? 1 : .1;
$('#chevron').animate({'opacity':opacity},speed);
},speed);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chevron">Chevron</div>

Your code is recursing infinitely.
I changed it to add a parameter goingDown, which when true will cause the animation to hide the chevron, and set the state of a global variable downState to match goingDown. I removed the recursion, you don't need it.
var downState = null;
function animateChevron(goingDown) {
if (!goingDown) {
$('#chevron').animate({
'opacity': 1
}, 500);
} else {
$('#chevron').animate({
'opacity': 0.1
}, 500);
}
downState = goingDown;
}
$(document).ready(function() {
animateChevron(true);
});
#chevron {
font-size: 28px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="chevron">
ยป
</div>

Here is another solution due to the solution I offered first (can still be found at the bottom of this answer) didn't fit the needs of the asker.
According to the following question async callbacks will not cause any stack overflows.
Will recursively calling a function from a callback cause a stack overflow?
(function animateChevron() {
// Chevron visible at this point
$('#chevron').animate({'opacity': 0}, 500, () => {
// Chevron invisible at this point
$('#chevron').animate({'opacity': 1}, 500, animateChevron);
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chevron">Chevron</div>
I found a very neat solution right here at stackoverflow as alternative.
How to make blinking/flashing text with css3?
Code snippet by Mr. Alien:
(function blink() {
$('#chevron').fadeOut(500).fadeIn(500, blink);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chevron">Chevron</div>

Related

loop jQuery simple animated lines 3 times

Update: Due to vagueness of my question - resulted in a broad answer that doesn't really apply (as you can see below). My full question and problem migrated to -- > add a loop function around 3 small animations within larger animation functions
How to define the below to loop / play specifically 3 times in a row before stopping (simple line animation with jQuery):
My animation works.. it's basically three lines that come out one at a time that draw a triangle... It's the looping 3 times i need.
var padding = $('.conn-1').css('padding');
var line_anim = 700;
$('.replay').hide();
$('.conn-1').width('100%').animate({'height':'100%'},line_anim,
function () {
$('.conn-2').height('100%').animate({'width':'100%'}, line_anim,
function () {
$('.conn-3').css({width:'100%'}).animate({'height':'100%'}, line_anim,
function(){replay();})
}
);
}
);
//$('.conn-2').width(0).siblings('.connect-lines').css('margin',0);
}, 2000);
});
},5000);
}
Updated code via answered suggestions -- the below didn't run / work with the looping; any additional thoughts?
function animAll(remainingLoops){
if(!remainingLoops) return;
$('.replay').hide();
$('.conn-1').width('100%').animate({'height':'100%'},line_anim, function () {
$('.conn-2').height('100%').animate({'width':'100%'}, line_anim, function () {
$('.conn-3').css({width:'100%'}).animate({'height':'100%'}, line_anim, function(){
animAll(remainingLoops-1);
// replay();})
});
});
}
);
}
);
//$('.conn-2').width(0).siblings('.connect-lines').css('margin',0);
}, 2000);
});
},5000);
}
function animAll(remainingLoops){
if(!remainingLoops) return;
$('#blue').width(50).animate({width: '100%'}, function(){
$('#red').width(50).animate({width: '100%'}, function(){
$('#green').width(50).animate({width: '100%'}, function(){
animAll(remainingLoops-1);
});
});
});
}
animAll(3);
div{height:50px;background:#00f}#red{background:red}#green{background:green}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="blue"></div>
<div id="red"></div>
<div id="green"></div>

jQuery animation setup callback throws error

I want to implement a jQuery animation callback method progress or step,
but in either case I'm getting the following error:
NS_ERROR_IN_PROGRESS: Component returned failure code: 0x804b000f (NS_ERROR_IN_PROGRESS) [nsICacheEntry.dataSize]
I searched a lot but not able to find anything in context, I am kind of stuck here, please suggest what could cause this error?
In fiddle i tried with step and progress and its working there , but not able to get it worked in my code, I am just looking, has some one faced such kind of error in jquery animation?
The sample code is:
this.taskHandle.find('img').stop(true, true).animate({
//todo//
top: vtop, // this.taskHandle.outerHeight(),
//'top': 0 - $('.target.upper').height(),
width: 0,
opacity: 0
}, {
duration: 2000,
step: function(){
console.log('I am called');
}
},
$.proxy(function() {
// some css clearing method
}, {
// some further actions after animation completes
})
);
You have some semantic errors going on here. I'm going to repost your code, formatted for easier reading:
this.taskHandle.find('img')
.stop(true, true)
.animate(
{
//todo//
top: vtop , // this.taskHandle.outerHeight(),
//'top' : 0 - $('.target.upper').height(),
width : 0,
opacity : 0
},
{
duration:2000,
step: function() {
console.log('I am called');
}
},
$.proxy(
function() {
// some css clearing method
},
{
// some further actions after animation completes
}
)
);
First: animate() doesn't accept 3 parameters (at least not those 3 parameters). I'm not sure what you are trying to do with your css clearing method, but anything you wan't to happen after the animation is complete should be in the complete method that you add right next to the step method.
Second: $.proxy() needs to have the context in which you want it to run as the second parameter, not some other"complete"-function.
So here is a slightly modified example which works. You can try it yourself in this fiddle.
var vtop = 100;
$('div')
.stop(true, true)
.animate(
{
top: vtop,
width: 0,
opacity : 0
},
{
duration: 2000,
step: function() {
console.log('I am called');
},
complete: function () {
alert('complete');// some further actions after animation completes
}
}
);
You could use Julian Shapiro's Velocity.js, which animations are (arguable) faster than jQuery and CSS (read this for more)
It allows you to use callbacks such as :
begin
progress
complete
like :
var vtop = 100;
jQuery(document).ready(function ($) {
$('div').find("img").velocity({
top: vtop,
width: 0,
opacity: 0
}, {
duration: 2000,
begin: function (elements) {
console.log('begin');
},
progress: function (elements, percentComplete, timeRemaining, timeStart) {
$("#log").html("<p>Progress: " + (percentComplete * 100) + "% - " + timeRemaining + "ms remaining!</p>");
},
complete: function (elements) {
// some further actions after animation completes
console.log('completed');
$.proxy( ... ); // some css clearing method
}
});
}); // ready
Notice that you just need to replace .animate() by .velocity()
See JSFIDDLE

Query animate() doesnt working

I have the following code:
var isOn = false;
$('.switch').on("click",function(){
if (isOn){
$('.toggle').animate({
left:"18px"
},10,"linear",
{
complete: function(){
$('#label').text("ON");
}
});
isOn = false;
} else {
$('.toggle').animate({
left:"4px"
}, 10,"linear",
{
complete: function(){
$('#label').text("OFF");
}
});
isOn = true;
}
});
http://codepen.io/pietrofxq/pen/LpzDE?editors=001
It is a switch on/off made with jquery. It was working without the animate() method.
I was doing the animation with css, but it was buggy in Internet Explorer.
Here is the original effect: http://codepen.io/anon/pen/iwatp
Why the complete function in the first link isn't working?
EDIT: This code is working but still doesnt work properly on IE
You seem to be mixing the two different signatures of the .animate function. If you pass the duration and the easing directly as arguments, you have to do the same for the callback function:
$('.toggle').animate({left: "18px"}, 10, "linear", function(){
$('#label').text("ON");
});
OR you have to pass two objects:
$('.toggle').animate(
{
left:"18px"
},
{
duration: 10,
easing: "linear",
complete: function(){
$('#label').text("ON");
}
}
);
now it will work. please check the jsfiddle link
http://jsfiddle.net/banded_krait/da2kE/
I removed some brackets and complete: array key from your code and hope this will work for you.

javascript animate div 100px left then 100px right?

can someone please help i am trying to animate a div so that it moves 100px to the left and then returns back to its original position/so moves back over to the right by 100px.
i want it to do this 5 times before stoping the animation.
can someone please show me how to get this to work thanks.
<script>
function loop() {
$('.sign_up').animate({right:'+=100px'}, 1000, function() {
$(this).animate({left:'-=100px'}, 1000, function() {
loop();
});
});
}
$(function() {
loop();
});
</script>
You can use a counter to determine when to stop looping. For example:
<script type="text/javascript">
var loopCount = 0;
function loop() {
$('.sign_up').animate({ left: '-=100px' }, 1000, function () {
$(this).animate({ left: '+=100px' }, 1000, function () {
loopCount++;
if (loopCount < 5)
loop();
});
});
}
$(function () {
loop();
});
</script>
I also switched the first animate statement to animate to the left using the left css property instead of right. This code worked for for me when I declared the sign_up div as follows:
<div class="sign_up" style="position:absolute;top:300px;left:300px;width:200px;height:200px;background:Green;">
Hello!
</div>
UPDATE
Here's a working jsfiddle: http://jsfiddle.net/peFVT/

How to run two jQuery animations simultaneously?

Is it possible to run two animations on two different elements simultaneously? I need the opposite of this question Jquery queueing animations.
I need to do something like this...
$('#first').animate({ width: 200 }, 200);
$('#second').animate({ width: 600 }, 200);
but to run those two at the same time. The only thing I could think of would be using setTimeout once for each animation, but I don't think it is the best solution.
yes there is!
$(function () {
$("#first").animate({
width: '200px'
}, { duration: 200, queue: false });
$("#second").animate({
width: '600px'
}, { duration: 200, queue: false });
});
That would run simultaneously yes.
what if you wanted to run two animations on the same element simultaneously ?
$(function () {
$('#first').animate({ width: '200px' }, 200);
$('#first').animate({ marginTop: '50px' }, 200);
});
This ends up queuing the animations.
to get to run them simultaneously you would use only one line.
$(function () {
$('#first').animate({ width: '200px', marginTop:'50px' }, 200);
});
Is there any other way to run two different animation on the same element simultaneously ?
I believe I found the solution in the jQuery documentation:
Animates all paragraph to a left style
of 50 and opacity of 1 (opaque,
visible), completing the animation
within 500 milliseconds. It also will
do it outside the queue, meaning it
will automatically start without
waiting for its turn.
$( "p" ).animate({
left: "50px", opacity: 1
}, { duration: 500, queue: false });
simply add: queue: false.
If you run the above as they are, they will appear to run simultaenously.
Here's some test code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script>
$(function () {
$('#first').animate({ width: 200 }, 200);
$('#second').animate({ width: 600 }, 200);
});
</script>
<div id="first" style="border:1px solid black; height:50px; width:50px"></div>
<div id="second" style="border:1px solid black; height:50px; width:50px"></div>
While it's true that consecutive calls to animate will give the appearance they are running at the same time, the underlying truth is they're distinct animations running very close to parallel.
To insure the animations are indeed running at the same time use:
$(function() {
$('#first').animate({..., queue: 'my-animation'});
$('#second').animate({..., queue: 'my-animation'});
$('#first,#second').dequeue('my-animation');
});
Further animations can be added to the 'my-animation' queue and all can be initiated provided the last animation dequeue's them.
Cheers,
Anthony
See this brilliant blog post about animating values in objects.. you can then use the values to animate whatever you like, 100% simultaneously!
http://www.josscrowcroft.com/2011/code/jquery-animate-increment-decrement-numeric-text-elements-value/
I've used it like this to slide in/out:
slide : function(id, prop, from, to) {
if (from < to) {
// Sliding out
var fromvals = { add: from, subtract: 0 };
var tovals = { add: to, subtract: 0 };
} else {
// Sliding back in
var fromvals = { add: from, subtract: to };
var tovals = { add: from, subtract: from };
}
$(fromvals).animate(tovals, {
duration: 200,
easing: 'swing', // can be anything
step: function () { // called on every step
// Slide using the entire -ms-grid-columns setting
$(id).css(prop, (this.add - this.subtract) + 'px 1.5fr 0.3fr 8fr 3fr 5fr 0.5fr');
}
});
}
Posting my answer to help someone, the top rated answer didn't solve my qualm.
When I implemented the following [from the top answer], my vertical scroll animation just jittered back and forth:
$(function () {
$("#first").animate({
width: '200px'
}, { duration: 200, queue: false });
$("#second").animate({
width: '600px'
}, { duration: 200, queue: false });
});
I referred to: W3 Schools Set Interval and it solved my issue, namely the 'Syntax' section:
setInterval(function, milliseconds, param1, param2, ...)
Having my parameters of the form { duration: 200, queue: false } forced a duration of zero and it only looked at the parameters for guidance.
The long and short, here's my code, if you want to understand why it works, read the link or analyse the interval expected parameters:
var $scrollDiv = '#mytestdiv';
var $scrollSpeed = 1000;
var $interval = 800;
function configureRepeats() {
window.setInterval(function () {
autoScroll($scrollDiv, $scrollSpeed);
}, $interval, { queue: false });
};
Where 'autoScroll' is:
$($scrollDiv).animate({
scrollTop: $($scrollDiv).get(0).scrollHeight
}, { duration: $scrollSpeed });
//Scroll to top immediately
$($scrollDiv).animate({
scrollTop: 0
}, 0);
Happy coding!

Categories

Resources