0

I am having trouble changing the contents of a div. What I want to achieve is wait for the animation to end and then change the content to launch the animation to reveal the new info. This code works from time to time, meaning sometimes it hangs (isWorking never becomes false, because animation freezes or animation never has the time to finish from the constant looping inside the while.) Is there a way to wait for the animation to end and then change the content? (The way you see it below allows me to browse for the new content while the animation is ongoing which saves time for the end user.) Is there a way to catch when the animation ends?

 function DesignResults(InnerHTML) {
            while(isWorking){
            }
            $("#holder").html(InnerHTML);
            ShowSearch(true);
    }
    var isWorking = false;
    function ShowSearch(show) {
            isWorking = true;
            var outer = $("#outer");
            var inner = $("#inner");
            var height = 0;
            if (show == true)
                height = inner.outerHeight();
            var loaderHeight
            if (height > 0) {
                loaderHeight = 0;
            } else {
                loaderHeight = 31;
            }
            outer.animate({
                'height': height + "px"
            }, 1600, function () {
                $("#loading").animate({ 'height': loaderHeight + "px" }, 900, function () { });
                isWorking = false;
            });
    }

I understand that $(elem).is(':animated') will give me if the animation is still in progress, but that still freezes everything due to the constant looping of the while. Can anyone point me to the right direction?

EDIT: I guess I am misunderstood. Here is the plan I want to achieve:

  1. Start hiding animation.
  2. While the animation is hiding I am launching another function to get the content If I get the content faster I wish to wait for the animation to end then change the content and show the layer again. There isn't a issue here if the data takes more than a second to return

I agree that i can do it after the animation completes as you suggested, but I have put the animation to almost 1 second execute time and that time can be used for the data to be pulled from the database. I am looking for the most effective code.

user2227904
  • 679
  • 1
  • 8
  • 27

2 Answers2

4

The last parameter in this function:

$("#loading").animate({ 'height': loaderHeight + "px" }, 900, function () { });

Is the 'complete' function. This function is called when the animation is complete.

So, you can do something in this function when it's complete, like so:

$("#loading").animate({ 'height': loaderHeight + "px" }, 900, function () { 
    alert('animations complete!');
});

----Edit----

Based on your edits, you probably want to do something like this.

  1. Have a variable that will let you know when both are finished:

    var signal = 0;
    
  2. Have a function to change your content with this in it:

    function changeContent() {
        signal++;
        if (signal === 2) {
            // change the content code here
            signal = 0;
        }
    }
    
  3. When the animation is finished, call:

    changeContent();
    
  4. When you've grabbed the data, call:

    changeContent();
    

When changeContent() is called the first time by either function, it will increment signal to 1 and exit the function. Then on the second time, it will increment signal to 2. Since signal === 2, you know that both the animation and grabbing the data is complete, so you can now change your content.

The good part about using an integer to do this, is if you want to have 3, 4, 5+ functions finish working before changing your content. In this case you just have to change the condition by increasing the number in if (signal === 2).

David Sherret
  • 101,669
  • 28
  • 188
  • 178
  • I found a workaround with setInterval() Every 0.5 seconds it launches the change of the content, if the isWorking = True it skips the change of data and if it's false it changes and launches the animation to show the new data and clears the interval. – user2227904 Jul 25 '13 at 08:21
  • That's basically the same principle as a spinlock. That will work as well. Not as efficient, but the inefficiency is completely negligible. You could probably lower the `setInterval` down to 0.1 seconds to make it a bit more responsive. – David Sherret Jul 25 '13 at 13:13
1

Just add the additional task here

$("#loading").animate({ 'height': loaderHeight + "px" }, 900, function () { /* Change Content */ });

Than it would be execute after the animation

Michael Walter
  • 1,427
  • 12
  • 28