Особенности jQuery методов fadeIn, fadeOut и fadeTo

в 22:54, , рубрики: javascript, jquery, Веб-разработка, метки:

Итак, рассмотрим что же не так в методах 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js