When animations go wrong it’s usually in the timing. Perhaps the browser can’t keep up with all that it’s asked to do or the operating system is bogged down by other tasks. In any case the lack of enough working memory or CPU cycles will have animations stacking up until there are enough resources to do all those fancy moves.
Some animations run continuously and others may be controlled by setting timers or stopping the animations at predetermined times. Other animations happen after some event has occurred, like when a user mouses over an element on the page or clicks a button.
Animations created with the jQuery InnerFade plugin run continuously, which may create a problem if the users’ computer resources aren’t up to the job.
It was noted that an InnerFade news ticker animation of links worked fine and as expected when the browser tab was left open and running. Working with another tab open and going back to the news ticker site, the news items got stacked onto one another so that the text was unreadable and the timing was double time.
Reloading the page or waiting for a couple of seconds to pass brought the expected behavior back. The animations caught up to where they should have been and the behavior continued as expected.
I’m not exactly sure why the animations stacked up in my page and not in the demo page by the plugin author, but I found a solution to this stacking problem.
jQuery lets us use a stop() action to clear the previously requested animations that haven’t finished yet. Optional parameters for the stop() action are clearQueue and gotoEnd, which are false by default.
To use the stop() action in this case, set both parameters to true. This will clear all animations in the queue and jump to the place where the action should be at now.
If it were important to catch up to the latest animation, use true for the optional gotoEnd parameter. When set to true, the gotoEnd parameter figures out what the screen should look like at the end of the present set of animations in the queue and goes there.
In the section of the code that responds to the slide or fade settings, I used the stop() action to clear the queue and catch up. The InnerFade plugin was altered on lines 93 and 96 (of the original script) by inserting .stop(true,true) just before the fadeOut() or slideUp() methods.
line 93...$(elements[last]).stop(true,true).slideUp(settings.speed); line 96...$(elements[last]).stop(true,true).fadeOut(settings.speed);
Below is the portion of the original script that has been modified (on lines 3 and 6 here):
$.innerfade.next = function(elements, settings, current, last) { if (settings.animationtype == 'slide') { $(elements[last]).stop(true,true).slideUp(settings.speed); $(elements[current]).slideDown(settings.speed); } else if (settings.animationtype == 'fade') { $(elements[last]).stop(true,true).fadeOut(settings.speed); $(elements[current]).fadeIn(settings.speed, function() { removeFilter($(this)[0]); });
The script now works even better!
When two separate link lists were animated with the InnerFade plugin on the same page, the first one stacked up and the second list went blank when the stop() action was used with only the first parameter set to true, so it was important to set both the clearQueue and gotoEnd parameters to true.
The stop() action also comes in handy to clear the queue when event-driven animations get backed up from too much user input, like mousing over and out too fast.
An oddity in all this is that I couldn’t replicate the bad behavior (of the original plugin) inside of WordPress. The stacking up of animations was noticed in a static page outside of WordPress. To see the original and improved InnerFade plugins in action, go to the Good Ideas static page.
Is there some way that WordPress manages the scripts differently? I dunno, but the take away message here is to make sure and test your scripts to see how they act in various circumstances.