web-dev-qa-db-fra.com

animation de addClass / removeClass avec jQuery

J'utilise jQuery et jQuery-ui et souhaite animer divers attributs sur divers objets.

Afin d'expliquer le problème ici, je l'ai simplifié en une division qui passe du bleu au rouge lorsque l'utilisateur passe la souris dessus.

Je peux obtenir le comportement que je souhaite en utilisant animate(), mais les styles que j'anime doivent être dans le code d'animation et sont donc distincts de ma feuille de style. (voir exemple 1)

Une alternative consiste à utiliser addClass() et removeClass() mais je n'ai pas été en mesure de recréer le comportement exact que je peux obtenir avec animate(). (voir exemple 2)


Exemple 1

Jetons un coup d'oeil au code que j'ai avec animate():

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( {backgroundColor:'blue'}, {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( {backgroundColor:'red'}, {duration:500});
  });

il affiche tous les comportements que je recherche:

  1. Anime en douceur entre le rouge et le bleu.
  2. Aucune animation ne "surcharge" lorsque l'utilisateur déplace sa souris rapidement dans la div.
  3. Si l'utilisateur déplace sa souris vers le bas pendant que l'animation est en cours de lecture, la transition entre l'état "intermédiaire" actuel et le nouvel état "objectif" est correcte.

Mais comme les modifications de style sont définies dans animate(), je dois modifier les valeurs de style ici et je ne peux pas simplement les faire pointer sur ma feuille de style. Cette "fragmentation" de la définition des styles est quelque chose qui me dérange vraiment.


Exemple 2

Voici ma meilleure tentative actuelle en utilisant addClass() et removeClass (notez que pour que l'animation fonctionne, vous avez besoin de 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});
  });

Ceci expose à la fois les propriétés 1. et 2. de mes exigences d'origine, cependant 3 ne fonctionne pas.

Je comprends la raison de ceci:

Lors de l'animation de addClass() et removeClass(), jQuery ajoute un style temporaire à l'élément, puis incrémente les valeurs appropriées jusqu'à atteindre les valeurs de la classe fournie, puis ajoute/supprime réellement la classe.

À cause de cela, je dois supprimer l'attribut style, sinon, si l'animation est arrêtée à mi-parcours, l'attribut style restera et écraserait toutes les valeurs de classe, car les attributs de style d'une balise ont une importance plus grande que les styles de classe.

Toutefois, lorsque l'animation est terminée à mi-parcours, la nouvelle classe n'a pas encore été ajoutée. Par conséquent, avec cette solution, la couleur passe à la couleur précédente lorsque l'utilisateur déplace la souris avant la fin de l'animation.


Ce que je veux idéalement, c'est pouvoir faire quelque chose comme ça:

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( getClassContent('blue'), {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( getClassContent('red'), {duration:500});
  });

getClassContent renverrait simplement le contenu de la classe fournie. Le point clé est que de cette façon, je n'ai pas besoin de conserver mes définitions de style partout, mais de les conserver dans des classes de ma feuille de style.

214
Johannes

Puisque vous n'êtes pas inquiet pour IE, pourquoi ne pas simplement utiliser les transitions CSS pour fournir l'animation et jQuery pour changer les classes. Exemple en direct: 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;
}
301
tw16

Une autre solution (mais cela nécessite jQueryUI comme l'a souligné Richard Neil Ilagan dans les commentaires): -

addClass, removeClass et toggleClass acceptent également un deuxième argument. la durée de passage d'un état à l'autre.

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

Voir jsfiddle: - http://jsfiddle.net/6hvZT/1/

89
Omar Tariq

Vous pouvez utiliser jquery ui's switchClass , voici un exemple:

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

Ou voyez ceci jsfiddle .

37
by0

Vous avez juste besoin de jQuery UI effects-core (13 Ko), pour activer la durée de l'ajout (tout comme Omar Tariq l'a souligné)

12
Patrick

Je cherchais cela, mais je voulais avoir un taux de transition différent pour les entrées et les sorties.

C'est ce que j'ai fini par faire:

//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');
    });
});

Cela change instantanément la couleur de fond en # 5eb4fc puis revient progressivement à la normale en 2 secondes.

Voici un violon

4
Tj Gienger

Bien que la question soit assez ancienne, j'ajoute des informations qui ne figurent pas dans les autres réponses.

L'OP utilise stop () pour arrêter l'animation en cours dès que l'événement est terminé. Cependant, utiliser la bonne combinaison de paramètres avec la fonction devrait aider. par exemple. stop (true, true) ou stop (true, false) car cela affecte bien les animations en file d'attente.

Le lien suivant illustre une démonstration montrant les différents paramètres disponibles avec stop () et leur différence avec finish ().

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

Bien que l'OP n'ait rencontré aucun problème d'utilisation de JqueryUI, il est destiné aux autres utilisateurs qui peuvent rencontrer des scénarios similaires mais ne peuvent pas utiliser JqueryUI/qui doivent également prendre en charge IE7 et 8.

2
Anurag