анімація addClass / removeClass з jQuery


225

Я використовую jQuery і jQuery-ui і хочу анімувати різні атрибути на різних об'єктах.

Для пояснення цієї проблеми я спростив її до одного діва, який змінюється від синього на червоний, коли користувач переходить на нього.

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


1
Які версії IE вам потрібно підтримувати? Чи були б ви задоволені IE9? Або вам потрібно підтримувати нижчі?
tw16

1
Я взагалі не дбаю про IE, щоб бути чесним. Це все перевірено лише у веб-браузерах (сафарі / хром).
Йоганнес

як getClassContentце виглядає?
sreginogemoh

Відповіді:


311

Оскільки вас не турбує 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;
}

14
З 2015-06-12 це підтримується у - IE 10+ - Chrome 26+ - FireFox 16+ - Safari 6.1+ - Opera 12.1+ -webkit, -moz, -o потрібне лише для старих браузерів. Ви, мабуть, можете залишити його, щоб заощадити місце.
clst

3
@clst, я вважаю за краще сумісність із старими веб-переглядачами, а не економити кілька байтів місця.
Арман Н

95

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

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

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

Дивіться jsfiddle: - http://jsfiddle.net/6hvZT/1/


28
Зауважте, що для цього потрібен інтерфейс jQuery. jQuery з вікна не підтримує анімацію для xxxClass()функцій.
Річард Ніл Ілаган

@Richard Ніл Ілаган: Дякую за повідомлення. Я дуже пропустив цю точку.
Омар Тарік

4
Чи можете ви вказати, який файл потрібно завантажити та включити у файл .html, щоб я міг використовувати jQueryUI лише для xxxClassанімації, яка працює між собою?
натрійнітрат

[jqueryui.com] (jqueryui.com) @sodiumnitrate
joe_young

1
Це рішення також не анімує так само, як слайд () або анімація (). Значення мілісекунд - це затримка, яка не є анімацією.
Солона Армстронг

38

Ви можете використовувати jquery ui, ось switchClassприклад:

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

Або дивіться цю jsfiddle .


1
-1. Ви не відповідали обмеженням 1, 2 і 3, які я вказав у початковій публікації. Зокрема, SwitchClass погано обробляє вимоги 2 та 3.
Йоганнес

12

Вам просто потрібне ядро ефекту інтерфейсу jQuery (13 КБ), щоб увімкнути тривалість додавання (так само, як це вказував Омар Тарік)


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

Ось загадка


2

Хоча питання досить старе, я додаю інформацію, яка не присутня в інших відповідях.

ОП використовує stop () для зупинки поточної анімації, як тільки подія завершується. Однак використання правильного поєднання параметрів з функцією повинно допомогти. напр. зупинка (правда, правда) або стоп (правда, хибність), оскільки це добре впливає на анімацію в черзі.

Наступне посилання ілюструє демонстраційну версію, яка показує різні параметри, доступні для зупинки (), і як вони відрізняються від закінчення ().

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

Хоча у ОП не було проблем із використанням JqueryUI, це стосується інших користувачів, які можуть натрапити на подібні сценарії, але не можуть використовувати JqueryUI / потребувати підтримки IE7 та 8 теж.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.