Анимация addClass/removeClass с jQuery
Я использую jQuery и jQuery-ui и хочу анимировать различные атрибуты на разных объектах.
Чтобы объяснить эту проблему, я упростил ее до одного div, который меняется от синего до красного, когда пользователь перебирает его.
Я могу получить поведение, которое я хочу при использовании animate()
, однако при этом стили, которые я анимация, должны быть в коде анимации и поэтому отделены от моей таблицы стилей. (см. пример 1)
Альтернативой является использование addClass()
и removeClass()
, но я не смог воссоздать точное поведение, которое я могу получить с помощью animate()
. (см. пример 2)
Пример 1
Посмотрим на код, который у меня есть с animate()
:
$('#someDiv')
.mouseover(function(){
$(this).stop().animate( {backgroundColor:'blue'}, {duration:500});
})
.mouseout(function(){
$(this).stop().animate( {backgroundColor:'red'}, {duration:500});
});
отображает все поведение, которое я ищу:
- Анимирует плавно между красным и синим.
- Отсутствие анимации "переизбытка", когда пользователь быстро перемещает свою мышь в и из div.
- Если пользователь перемещает мышь в/в, пока анимация все еще воспроизводится, она корректно работает между текущим состоянием "halfway" и новым состоянием "цель".
Но поскольку изменения стиля определены в animate()
, я должен изменить значения стиля там и не могу просто указать его на мою таблицу стилей. Эта "фрагментация" того, где определены стили, - это то, что меня действительно беспокоит.
Пример 2
Вот моя лучшая попытка с использованием addClass()
и removeClass
(обратите внимание, что для работы анимации вам нужно jQuery-ui):
//assume classes 'red' and 'blue' are defined
$('#someDiv')
.addClass('blue')
.mouseover(function(){
$(this).stop(true,false).removeAttr('style').addClass('red', {duration:500});
})
.mouseout(function(){
$(this).stop(true,false).removeAttr('style').removeClass('red', {duration:500});
});
Это показывает как свойство 1., так и 2. моих первоначальных требований, однако 3 не работает.
Я понимаю причину этого:
При анимации addClass()
и removeClass()
jQuery добавляет временный стиль к элементу и затем увеличивает соответствующие значения до тех пор, пока они не достигнут значений предоставленного класса, и только тогда он фактически добавит/удалит класс.
Из-за этого мне нужно удалить атрибут стиля, иначе, если анимация остановится наполовину, атрибут стиля останется и будет постоянно перезаписывать любые значения класса, поскольку атрибуты стиля в теге имеют более важное значение, чем стили классов.
Однако, когда анимация выполнена на полпути, она еще не добавила новый класс, и поэтому с этим решением цвет переходит к предыдущему цвету, когда пользователь перемещает свою мышь до завершения анимации.
В идеале я хочу сделать что-то вроде этого:
$('#someDiv')
.mouseover(function(){
$(this).stop().animate( getClassContent('blue'), {duration:500});
})
.mouseout(function(){
$(this).stop().animate( getClassContent('red'), {duration:500});
});
Где getClassContent
просто вернет содержимое предоставленного класса. Ключевым моментом является то, что таким образом мне не нужно сохранять определения стилей повсюду, но они могут содержать их в классах в моей таблице стилей.
Ответы
Ответ 1
Поскольку вы не беспокоитесь об IE, почему бы просто не использовать css-переходы для предоставления анимации и jQuery для изменения классов. Пример в реальном времени: http://jsfiddle.net/tw16/JfK6N/
#someDiv{
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
Ответ 2
Другое решение (но для него требуется jQueryUI, как указал Ричард Нил Илаган в комментариях): -
addClass, removeClass и toggleClass также принимает второй аргумент; продолжительность времени перехода от одного состояния к другому.
$(this).addClass('abc',1000);
См. jsfiddle: - http://jsfiddle.net/6hvZT/1/
Ответ 3
Вы можете использовать jquery ui switchClass
, Вот пример:
$( "selector" ).switchClass( "oldClass", "newClass", 1000, "easeInOutQuad" );
Или посмотрите jsfiddle.
Ответ 4
Вам нужно всего лишь jQuery UI-эффект-ядро (13KB), чтобы включить длительность добавления (как указывал Омар Тарик)
Ответ 5
Я изучал это, но хотел иметь другую скорость перехода для входа и выхода.
Вот что я сделал:
//css
.addedClass {
background: #5eb4fc;
}
// js
function setParentTransition(id, prop, delay, style, callback) {
$(id).css({'-webkit-transition' : prop + ' ' + delay + ' ' + style});
$(id).css({'-moz-transition' : prop + ' ' + delay + ' ' + style});
$(id).css({'-o-transition' : prop + ' ' + delay + ' ' + style});
$(id).css({'transition' : prop + ' ' + delay + ' ' + style});
callback();
}
setParentTransition(id, 'background', '0s', 'ease', function() {
$('#elementID').addClass('addedClass');
});
setTimeout(function() {
setParentTransition(id, 'background', '2s', 'ease', function() {
$('#elementID').removeClass('addedClass');
});
});
Это мгновенно превращает цвет фона в # 5eb4fc, а затем медленно возвращается в нормальное состояние в течение 2 секунд.
Здесь fiddle
Ответ 6
Хотя вопрос довольно старый, я добавляю информацию, отсутствующую в других ответах.
OP использует stop(), чтобы остановить текущую анимацию, как только событие завершится. Однако использование правильного сочетания параметров с функцией должно помочь. например. stop (true, true) или stop (true, false), так как это хорошо влияет на очереди анимации.
Следующая ссылка иллюстрирует демонстрацию, в которой показаны различные параметры, доступные с помощью stop() и как они отличаются от финиша().
http://api.jquery.com/finish/
Хотя у OP не было проблем с использованием JqueryUI, это касается других пользователей, которые могут сталкиваться с подобными сценариями, но не могут использовать JqueryUI/должны также поддерживать IE7 и 8.