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?

Reply via email to