In the application I am developing I have been using Erik's excelent effects queueing plugin to que classes of animations up one after another. My code for setting up the effects queueing was as follows:
{ var animList = new Array; var thisQueue = null; // Get elements to show and hide var elemsToMove = $('.move'); var elemsToHide = $('.hide'); var elemsToShow = $('.show'); // Hide all shown elements that are marked as unselected var thisQueue = $.fxQueue.start ({ selector : elemsToHide, effect : self.hide, params : ['slow'], }); // Move all selected elements to new locations $.fxQueue.add (thisQueue, { selector : elemsToMove, effect : 'moveProducts', params : ['slow'], }); // Show all hidden elements that are not marked as unselected $.fxQueue.add (thisQueue, { selector : elemsToShow, effect : self.show, params : ['slow'], }); }; This worked okay, but then an issue arose where if users operated the form controls while the animations were playing then weird stuff would happen. I thought I'd just disable the form when the user starts an animation and reenable it when the animation ends. I had to rewrite my function a little to make sure that the last item in the queue and only the last item reenabled the form so I rewrite it like this (I'm using alerts to stand in for the form enable statement as they make the problem more visible) { var animList = new Array; var thisQueue = null; // Build animation action list if (elemsToHide.length > 0) animList.push ({ selector : elemsToHide, effect : self.hide, params : [self.hideSpeed] }); if (elemsToMove.length > 0) animList.push ({ selector : elemsToMove, effect : 'moveProducts', params : [self.moveSpeed] }); if (elemsToShow.length > 0) animList.push ({ selector : elemsToShow, effect : self.show, params : [self.showSpeed] }); if (animList.length > 0) { // Tag the final item in the queue with the done callback animList [animList.length - 1].callback = function (){alert ('done');}; animList [animList.length - 1].callbackOnce = true; // Create effects queue while (animList.length > 0) { thisQueue? $.fxQueue.add (thisQueue, animList.shift ()): thisQueue = $.fxQueue.start (animList.shift ()); } } else alert ('Nothing to do'); }; I found this causes a problem in that the callback function that I thought would only be triggered at the very end of the sequence got triggered at the end of every step in the sequence. This would lead to the form being reenabled prematurely. I tried the following change: { var animList = new Array; var thisQueue = null; // Build animation action list if (elemsToHide.length > 0) animList.push ({ selector : elemsToHide, effect : self.hide, params : [self.hideSpeed], callback : function (){}, callbackOnce : true }); if (elemsToMove.length > 0) animList.push ({ selector : elemsToMove, effect : 'moveProducts', params : [self.moveSpeed], callback : function (){}, callbackOnce : true }); if (elemsToShow.length > 0) animList.push ({ selector : elemsToShow, effect : self.show, params : [self.showSpeed], callback : function (){}, callbackOnce : true }); if (animList.length > 0) { // Tag the final item in the queue with the done callback animList [animList.length - 1].callback = function (){alert ('done');}; // Create effects queue while (animList.length > 0) { thisQueue? $.fxQueue.add (thisQueue, animList.shift ()): thisQueue = $.fxQueue.start (animList.shift ()); } } else alert ('Nothing to do'); }; This nearly worked. The first time I called this function the result was that the alert would appear at the end of every point of the sequence like in my earlier attempt, but on subsequent calls the alert would only appear at the end of the sequence as I wanted to. I tried replacing the empty functions with alert ('a'), alert ('b') and alert ('c') for each respective step in the sequence. I found that on the first run through I'd get 'done' alerts for all steps in the sequence, but for subsequent run throughs I'd get 'a', 'b', 'done' as I expected and wanted to happen. Does anyone with experience with the plugin I'm using have any insight into what's going on here?