Итак, рассмотрим что же не так в методах fadeIn и fadeOut, которые, как утверждает документация, являются аналогами метода fadeTo, но имеют некоторые свои особенности. На первый взгляд ничего, всё написано в документации. Однако, это не всегда верно, и не все особенности можно найти в документации.
Началось все с простейшей анимации
Картинка заменяется на другую картинку, но сверстано так, что можно просто скрывать и показывать другую картинку. Анимация должна работать как самостоятельно так и по наведению указателя.
Первое, что пришло на ум:
target1.fadeIn(duration); // на новой картинке
target2.fadeOut(duration); // на прежней картинке
Вот, так просто и всё.
Но при быстрых движениях мышью туда-сюда очередь анимации накапливается, и после остановки указателя, мы наблюдаем еще какое-то время «мигающие» картинки. Непорядок. Исправляю.
target1.stop().fadeIn(duration); // на новой картинке
target2.stop().fadeOut(duration); // на прежней картинке
Пробуем. Работает! Красиво…
Но не тут то было...
Если очень быстро двигать указателем туда-сюда, можно «поймать» момент, когда анимация прекращается, как и положено, после вызова метода stop(), но следующая анимация не работает!
Код оперативной проверки этой ошибки:
target.fadeOut().stop().fadeIn()
В результате, картинка оставалась полупрозрачной вместо абсолютной не прозрачности, как и должно было быть после fadeIn.
Кстати, fadeOut отрабатывает как положено, или почти, не стал до конца разбираться. (Есть чем скрасить ближайший досуг вместо игры.)
Начал разбираться. Нашел древний баг: ссылка на трекер.
По ссылке можно найти несколько простых и быстрых примеров, как эту ошибку воспроизвести.
Почти через полтора года разработчики решили, что это не баг, а фича, и закрыли тему. Мол, кому мешает, пилите патч, а мы подумаем…
Решение
Решение простое — не использовать в таких ситуациях fadeIn, а вместе с ним может быть и fadeOut, и использовать fadeTo, который справляется с поставленной задачей согласно документации:
target1.stop().fadeTo(duration, 1); // вместо fadeIn на новой картинке
target2.stop().fadeTo(duration, 0); // вместо fadeOut на прежней картинке
Я подумал, что это не порядок, и не помешало бы, как минимум, об этом написать на русском языке.
В документации вряд ли когда-нибудь появится описание этой «фичи». Быстрее все же патч сделать, чем и займусь на досуге, если кто-нибудь меня не опередит.
К тому же, «поймал» я этот баг еще до использования stop(), передавая в fadeIn параметр queue со значение false, чтобы запустить одновременную анимацию. Результат аналогичный — анимация «зависала» на некотором близком к нулю значении opacity.
Автор: svtux