Функция обратного вызова непрозрачности jQuery. - PullRequest
1 голос
/ 28 ноября 2011

Я новичок в jQuery, и любая помощь будет принята с благодарностью!

Я пытаюсь написать простую функцию .animate, которая использует обратный вызов для запуска двух разных анимаций одна за другой.

Это код, который у меня сейчас есть:

  $(".spring_link").click(function(){
    $("#fall_content").animate({opacity:'hide'}, 9000, function() { 
      $("#spring_content").animate({opacity:'show', top:'0px'}, 'fast');
    });
  });

Я предполагал, что это приведет к скрытию #fall_content, а затем, когда это будет завершено, анимация, примененная к #spring_content, будетбыть запущеннымОднако обе анимации происходят одновременно.

Ответы [ 2 ]

3 голосов
/ 28 ноября 2011

Ваше предположение верно: Рабочая демоверсия .

Обратный вызов будет вызываться один раз для каждого объекта, которому соответствует селектор. Может быть, есть еще один элемент идентификатора fall_content, который уже спрятан? Потому что, если это так, это немедленно вызовет анимацию spring_content, не дожидаясь 9 секунд.

В указанном коде этого не может быть, потому что селектор $('#fall_content') никогда не может выдать более одного элемента. (Даже если бы было более чем одним элементом с одинаковым идентификатором, что не является допустимым HTML, jQuery выдаст только первый из этих элементов).

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

Чтобы обойти это, вы можете добавить not(':hidden') после вашего селектора; отфильтровывать все уже скрытые предметы из набора, что означает, что все оставшиеся предметы вызовут постепенное появление через 9 секунд.

Теперь, помимо того факта, что вы можете выполнять несколько вызовов одновременно, вы вводите еще одну возможную проблему - если все элементы в селекторе оказываются скрытыми. Запросить уже скрытый элемент для вызова обратного вызова, когда он скрыт, это совсем другая вещь - просто попросить без элементов вызвать обратный вызов, когда они скрыты:

// this will invoke the callback immediately
$('#already-hidden-element').animate({ opacity: 0 }, function() { ... });

// this will never invoke the callback
$('#id-that-does-not-exist').animate({ opacity: 0 }, function() { ... });

Так что, если это когда-либо будет проблемой для вас (и, возможно, даже если вы считаете, что это не изменится, потому что требования могут измениться позже, и в этом случае эту проблему будет сложно отследить), это одна из случаи, когда вы могли бы вместо этого попытаться ответить на тайм-аут:

var delay = 9000;
$('#bunch, #of, #IDs').animate({ opacity: 0 }, delay);
setTimeout(function() {
    $('#spring_content').animate({ opacity: 1 }, 'fast');
}, delay);

Теперь гарантируется, что ваш тайм-аут наступает только один раз, и всегда через 9 секунд после начала затухания. Обратите внимание, что мы говорим о сценарии, где все ваши элементы могут быть скрыты с самого начала. В этом сценарии вполне вероятно, что вы не хотите подождать 9 секунд, прежде чем показывать содержимое пружины, а вместо этого сразу же добавить его, как в исходном поведении animate. В этом случае вам придется установить задержку условно:

var elements = $('#bunch, #of, #IDs').not(':hidden');
var delay = elements.length == 0 ? 0 : 9000;

elements.animate({ opacity: 0 }, delay);
setTimeout(function() {
    $('#spring_content').animate({ opacity: 1 }, 'fast');
}, delay);
1 голос
/ 28 ноября 2011
var wait = setInterval(function() {
if( !$("#element1, #element2").is(":animated") ) {
    clearInterval(wait);
    // This piece of code will be executed
    // after element1 and element2 is complete.
}
}, 200);

Вы можете использовать установленный интервал для ожидания завершения другого действия.

...