Как предотвратить этот странный jQuery.animate() lag?

См. демонстрацию: jsFiddle

  • У меня есть простая форма, которая переключается при нажатии 'show'/'cancel'
  • Все работает отлично, но , если вы нажмете "отменить" вскоре после того, как будет раскрыта форма, есть хорошая 2-3-секундная отставание до начала анимации.
  • Это не происходит, если вы подождали несколько секунд, прежде чем нажать "отменить".
  • Задержка происходит во всех проверенных браузерах (например, ff, chrome).

1. Что может вызвать это отставание и как его можно предотвратить?

2. Есть ли лучший способ кодирования этой последовательности анимаций, который может предотвратить любые задержки?

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 });
            });
        });
    }
}

Ответ 1

Обязательно очистите очередь при запуске новой анимации с помощью stop():

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

Что вызывает отставание, так это то, что ваша длинная 2-секундная анимация $("#newResForm").animate({ opacity: 100 },2000) еще не закончена. JQuery помещает анимацию по умолчанию в очередь, ожидая завершения ее до начала следующего. Вы очищаете очередь с помощью stop(), что особенно полезно, если у вас есть две противоречивые анимации (например, открытая и закрытая анимация или анимация мыши/мыши). На самом деле вам может показаться хорошей практикой начать все ваши цепочки анимации с помощью stop(), если вы не знаете, что хотите, чтобы они стояли в очереди с предыдущими анимациями, которые могли произойти в другом месте.

Перейдя в более сложные темы, вы можете даже назвать разные очереди, чтобы, например, анимация зависания и анимация разворачивания/сглаживания обрабатывались отдельно для целей stop(). Для получения дополнительной информации см. Опцию queue (если задана строка) в http://api.jquery.com/animate/.

Ответ 2

Добавьте .stop() перед вашими вызовами анимации:

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() {
            /...
        });
    }
}

Ответ 3

Попробуйте использовать stop():

Вот 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);
        });
    });
}

Ответ 4

Пара вещей. Сначала проверьте JSFiddle, чтобы увидеть его в действии.

Проблема заключается в том, что ваше затухание в анимации занимает 2 секунды. Поэтому, когда вы закрываете его в течение 2 секунд, вы получаете задержку.

Я перекомпилировал ваши тайминги, чтобы гарантировать, что нет задержки. Посмотрите, понравитесь ли вы им и не стесняйтесь изменять их по своему усмотрению.

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');
}