问题
I am trying to create a flashing arrow. However when I execute this script in different browsers it behaves badly. IE says its out of memory, Chrome lags for a second and then behaves well and in firefox the animation is sticky.
Hope someone can work out a way that I can animate a flashing arrow smoothly. Thanks
aniPointer($('#arrow'));
function aniPointer(point) {
point.animate({opacity: 1.0}, {duration: 300})
.animate({opacity: 0.2}, {duration: 700})
.animate({opacity: 0.2}, {duration: 300})
.animate({opacity: 1.0}, {duration: 300, complete: aniPointer(point)})
}
回答1:
You're creating an infinite loop. You did so intentionally, but its running a lot faster than you think. complete takes a function reference. By adding the parens to the name of the callback function you are invoking aniPointer immediately and passing the return value to complete instead of passing a reference to aniPointer itself to be fired at some later time.
Even so, is that sequence really what you want to do?
You're doing:
go to 1.0 over 300ms
go to 0.2 over 700ms
go to 0.2 over 300ms
go to 1.0 over 300ms
repeat
Assuming you're starting at 1.0 this is actually:
wait 300ms
go to 0.2 over 700ms
wait 300ms
go to 1.0 over 300ms
repeat
If you're looking for a steady pulse you could do something like this:
function pulse($elem) {
return window.setInterval(function() {
$elem.animate({opacity: 0.2}, 700)
.animate({opacity: 1.0}, 300);
}, 1000);
}
Or if you were pausing intentionally you could do:
function pulse($elem) {
return window.setInterval(function() {
$elem.animate({opacity: 0.2}, 700);
window.setTimeout( function() {
$elem.animate({opacity: 1.0}, 300);
}, 1000);
}, 1600);
}
The return value would allow you to stop the animation if you wanted to like so:
var pulseIntervalId = pulse( $('#arrow_id') );
//some time later...
window.clearInterval(pulseIntervalId);
Either version would skirt the infinite loop issue, allowing the callback to have the reference to the pulsing element without being invoked prematurely.
回答2:
jasongetsdown's answer, although technically correct, is not very jQuery-esque. It also has the problem that if the animate takes slightly longer than it ought to, the window.setTimeout won't care and run a second instance in parallel, which might lead to all sorts of problems, so it's better to wait for the completion of the animate call before triggering a new one.
Here's another solution :
$.fn.pulse = function(lowOpacity, highOpacity) {
if (isNaN(+lowOpacity)) lowOpacity = 0.2;
if (isNaN(+highOpacity)) highOpacity = 1;
var that = this;
(this)
.delay(300)
.animate({opacity: lowOpacity}, 700)
.delay(300)
.animate({opacity: highOpacity}, 300, function() { that.pulse(lowOpacity, highOpacity); });
}
To use it you would do :
$('#elem').pulse();
To stop it you would do :
$('#elem').stop().clearQueue();
来源:https://stackoverflow.com/questions/3268351/jquery-animate-running-laggy