views:

175

answers:

2

Hey there,

I have a group of 4 divs and I'm looking to use jQuery to animate them once, then have a delay using delay(), and then run another set of animations on them, putting the divs back to their original configuration. Here's the code that I have:

//only selectors called 'option1' are affected by delay, and not 'option1 img' or 'option2'
$("#option1").showOption1().delay(3000).hideOption1();

//if i don't attach to #option1, delay doesn't work, but the animations that need to happen     simultaneously work
$(document).showOption1().delay(3000).hideOption1();

jQuery.fn.showOption1 = function(){

    $("#option2, #option3, #leftColumn").fadeOut(1000);

    $("#option1").css("zIndex", "5");

        $("#option1").animate({
        left: "370px",
        }, 1500);

    $("#option1 img").animate({ 
        width: "500px",
    }, 1500, function(){
        $("p.optionText").text('hello');
    });

 return this;
}

jQuery.fn.hideOption1 = function(){

$("#option1 img").animate({
    width: "175px",
}, 1500);


$("#option1").animate({
    left: "743px",
}, 1500);


$("#option2, #option3, #leftColumn").fadeIn(2000);

$("#option1").css("zIndex", "1");

return this;

}

I've tried two ways of running these two functions, as seen on lines 2 and 5. In the case of line 2, showOption1() will run fine, but then only

$("#option1").animate({
    left: "743px",
}, 1500);

will work from hideOption1() after the delay. The rest of hideOption1() is fired immediately after showOption1() finishes, ignoring the delay.

On the other hand, if I run line 5, all the code in hideOption1() runs simultaneously as desired, but ignores the delay entirely, running immediately after showOption1() finishes. How can I have all the code in hideOption1() run simultaneously after the delay?

Thanks much in advance!

A: 

.delay() doesn't exactly fit what you're trying to do, it adds a delay in the animation queue on each element that the selector matches. All the animations and delays are specific to the element, not tied to run together or the selector in any way. Since you're .fadeOut() and .animate() have different times (1000ms and 1500ms), they delay and start of the next animation is out of sync.

Also, there's no reason for putting these functions in the jQuery object, since you're not using this inside to do anything, instead I would just have this:

function showOption1 (){ ...code... }
//and
function hideOption1 (){ ...code... }

Or alternatively, have the selector matches (this) actually used, hiding the other options via a class for example. To run the hide animations all at once, I'd do the functions like above, then just call them like this:

showOption1();
setTimeout(hideOption1, 4500); //3000 + 1500 from animation, adjust if needed
Nick Craver
First off, thanks for looking this over! I changed the .fadeOut() and .animate() times to be the same; that was a mistake on my part. I had my functions like you suggested at first, but I then choose to attach them to jQuery so that I can take advantage of chaining and put in delay()s in between commands (and possibly use callback functions). So you don't think I can use delay() to affect multiple selectors? Can I return multiple selectors (like return this, return #option2, etc)?
Waleed
Also, could you clarify what you meant by "alternatively, have the selector matches (this) actually used, hiding the other options via a class for example"?
Waleed
A: 

With Nick's help, I've figured it out! I've used setTimeout as he suggested and had to do a bit of math to figure out each animation's start time and duration. Here's what I came up with:

var animationBuffer = 2000; //This is related to the 1500 ms I've specified for the length of the animations. I've simply added an extra half second buffer between the shinking of one option and the expanding of another. 
var firstOptionDuration = 6000; 
var secondOptionStart = animationBuffer + firstOptionDuration;
var secondOptionDuration = secondOptionStart + 5000 
var thirdOptionStart = secondOptionDuration + animationBuffer;
var thirdOptionDuration = thirdOptionStart + 4000 


showOption1(option1Text);
setTimeout(hideOption1, firstOptionDuration);
setTimeout(function(){showOption2(option2Text)}, secondOptionStart);
setTimeout(hideOption2, secondOptionDuration);
setTimeout(function(){showOption3(option3Text)}, thirdOptionStart);
setTimeout(hideOption3, thirdOptionDuration);


           function showOption1(string){
            $("#option2, #option3, #leftColumn").fadeOut(1500);


            $("#option1").css("zIndex", "5");


                $("#option1").animate({
                left: "370px",
                }, 1500);

            $("#option1 img").animate({ 

                width: "500px",
            }, 1500, function(){
                $("#option1 p").text(string);
            });

        }


        function hideOption1(){
            $("#option1 p").text(' ');

            $("#option1 img").animate({
                width: "175px",
            }, 1500);


            $("#option1").animate({
            //$(this).animate({
                left: "743px",
            }, 1500);


            $("#option2, #option3, #leftColumn").fadeIn(2000);

            $("#option1").css("zIndex", "1");

        }

        function showOption2(string){
            $("#option1, #option3, #leftColumn").fadeOut(1500);

            $("#option2").css("zIndex", "5");


                $("#option2").animate({
                left: "370px",
                top: "50px"
                }, 1500);

            $("#option2 img").animate({ 
                width: "500px",
            }, 1500, function(){
                $("#option2 p").text(string);
            });
        }

        function hideOption2(){
            $("#option2 p").text(' ');

            $("#option2 img").animate({
                width: "175px",
            }, 1500);


            $("#option2").animate({
                left: "743px",
                top: "225px"
            }, 1500);


            $("#option1, #option3, #leftColumn").fadeIn(2000);

            $("#option1").css("zIndex", "1");

        }

        function showOption3(string){
            $("#option2, #option1, #leftColumn").fadeOut(1500);

            $("#option3").css("zIndex", "5");

                $("#option3").animate({
                left: "370px",
                top: "50px"
                }, 1500);

            $("#option3 img").animate({ 
                width: "500px",
            }, 1500, function(){
                $("#option3 p").text(string);
            });
        }

        function hideOption3(){

            $("#option3 p").text(' ');

            $("#option3 img").animate({
                width: "175px",
            }, 1500);


            $("#option3").animate({
                left: "743px",
                top: "400px"
            }, 1500);


            $("#option2, #option1, #leftColumn").fadeIn(2000);

            $("#option1").css("zIndex", "1");

        }

I may even combine the show and hide functions, using setTimeout in the show function to trigger the hide function, since I don't expect to use a show without a hide.

Once again, thanks for your help!

Waleed