анимация 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});
  });

он отображает все поведение, которое я ищу:

  1. анимация плавно между красным и синим.
  2. нет анимации "overqueue-ing", когда пользователь быстро перемещает мышь в div и из него.
  3. если пользователь перемещает мышь / в то время как анимация все еще играет, она правильно облегчает между текущим состоянием "на полпути" и новым состоянием "цель".

но так как изменения стиля определены в 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 просто вернет содержимое предоставленного класса. Ключевым моментом является то, что таким образом я не должен держать свои определения стиля повсюду, но могу держать их в классах в моей таблице стилей.

6 ответов


поскольку вы не беспокоитесь о 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;
}

другое решение (но оно требует jQueryUI, как указал Ричард Нил Илаган в комментариях) :-

addClass, removeClass и toggleClass также принимает второй аргумент; продолжительность времени для перехода из одного состояния в другое.

$(this).addClass('abc',1000);

см. jsfiddle: -http://jsfiddle.net/6hvZT/1/


вы можете использовать jQuery ui switchClass вот пример:

$( "selector" ).switchClass( "oldClass", "newClass", 1000, "easeInOutQuad" );

или это jsfiddle.


вам просто нужно jQuery UI effects-core (13KB), чтобы включить продолжительность добавления (так же, как Омар Тарик указал)


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

вот что я делал:

//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 секунд.

здесь скрипка


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

OP использует stop (), чтобы остановить текущую анимацию, как только событие завершится. Однако использование правильного сочетания параметров с функцией должно помочь. например. stop (true, true) или stop(true,false), поскольку это хорошо влияет на анимацию в очереди.

следующая ссылка иллюстрирует демонстрацию, которая показывает различные параметры, доступные с stop (), и как они отличаются от заканчивать.)(

http://api.jquery.com/finish/

хотя у OP не было проблем с использованием JqueryUI, это для других пользователей, которые могут столкнуться с подобными сценариями, но не могут использовать JqueryUI/need для поддержки IE7 и 8.