16

See demo: jsFiddle

  • I have a simple form that is being toggled when clicking 'show' / 'cancel'
  • Everything works fine, but if you click 'cancel' shortly after the form is revealed, there's a good 2-3 seconds lag before the animation even begins.
  • This doesn't happen if you wait a few seconds before clicking 'cancel'.
  • The lag occures in all tested browsers (ie, ff, chrome).

1. What could cause this lag and how can it be prevented?

2. Is there a better way of coding this sequence of animations, that might prevent any lags?

HTML:

<div id="newResFormWrap">
    <form id="newResForm" action="" method="post" name="newRes">
        <div id="newResFormCont">
            <h3>title</h3>
            <p>form!</p>
            <div class="button" id="cancelNewRes">Cancel</div>
        </div>
    </form> 
</div>
<div class="button" id="addRes">show</div>

jQuery:

$("#newResForm").css({opacity: 0});

$("#addRes").click(function () {
    toggleNewRes()
});
$("#cancelNewRes").click(function () {
    toggleNewRes()
});

//toggleNewRes
function toggleNewRes() {
    if ($("#newResFormWrap").css('display') == "none") {//if hidden 
        $("#addRes").animate({ opacity: 0 }, 'fast', function() {
            $("#newResFormWrap").toggle('fast', function (){
                $("#newResForm").animate({ opacity: 100 },2000);
            });
        });
    } else { //if visible
        $("#newResForm").animate({ opacity: 0 }, 100,function() {
            $("#newResFormWrap").toggle('fast', function (){
                $("#addRes").animate({ opacity: 100 });
            });
        });
    }
}
Roy
  • 1,307
  • 1
  • 13
  • 29

4 Answers4

36

Make sure to clear the queue when starting a new animation with stop():

$("#newResForm").stop().animate({ opacity: 0 }, 100,function() {
        $("#newResFormWrap").toggle('fast', function (){
            $("#addRes").animate({ opacity: 100 }); 
                 // ...

What's causing the lag is the fact that your long 2-second animation $("#newResForm").animate({ opacity: 100 },2000) isn't finished yet. JQuery puts animations by default into a queue, waiting for one to finish before the next begins. You clear the queue with stop(), which is especially useful if you have two contradicting animations (like an open and close animation, or a mouseover/mouseout animation). In fact you might find it a good practice to begin all your animation chains with stop() unless you know you want them to queue with prior animations that may have occurred elsewhere.

Getting into more advanced topics, you can even name different queues, so that for example your hover animations and your expand/collapse animations are treated separately for the purposes of stop(). See the queue option (when given a string) at http://api.jquery.com/animate/ for more details.

Plynx
  • 11,341
  • 3
  • 32
  • 33
  • 5
    Pay attention that `.stop()` doesn't clear the queue, but merely stops the currently-running animation. In some cases, you might need to run instead `.stop(true)` which further clears all the queued animations as well, or even `.stop(true, true)` which further finishes the current animation immediately to the end point. More information on the [info page](https://api.jquery.com/stop/). In my case just the latter worked. – João Pimentel Ferreira Jul 15 '18 at 20:50
2

Add .stop() before your animate calls:

function toggleNewRes() {
    if ($("#newResFormWrap").css('display') == "none") {//if hidden 
        $("#addRes").stop().animate({ opacity: 0 }, 'fast', function() {
            /...
        });
    } else { //if visible
        $("#newResForm").stop().animate({ opacity: 0 }, 100,function() {
            /...
        });
    }
}
Michael Robinson
  • 29,278
  • 12
  • 104
  • 130
1

Try to use stop() :

Here is jsfiddle.

if ($("#newResFormWrap").is(':visible')) {//this way is eaiser to check
    $("#addRes").stop(true,false).animate({ opacity: 0 }, 'fast', function() {
        $("#newResFormWrap").toggle('fast', function (){
            $("#newResForm").animate({ opacity: 100 },2000);
        });
    });
}
Barlas Apaydin
  • 7,233
  • 11
  • 55
  • 86
1

Couple of things. First check out this JSFiddle to see it in action.

The problem you have is that your fade in animation takes 2 seconds. So when you close it within 2 seconds you experience a delay.

I recalibrated your timings to ensure there are no delay. See if you like them and feel free to change them as you like.

if ($("#newResFormWrap").css('display') == "none") {//if hidden 
    $("#addRes").animate({ opacity: 0 }, 'fast', function() {
        $("#newResFormWrap").toggle(0, function (){
            $("#newResForm").animate({ opacity: 100 },400);
        });
    });
} else { //if visible
    console.log('click');
    $("#newResForm").animate({ opacity: 0 }, 0, function() {
        console.log('animated');
        $("#newResFormWrap").toggle(0)
    });
    $("#addRes").animate({ opacity: 100 }, 'fast');
}
Split Your Infinity
  • 4,159
  • 1
  • 21
  • 19
  • I guess the stop() method mentioned above is also an important factor in the solution.. But thank you for your response – Roy Jan 30 '13 at 21:09