240 votes

animer addClass/removeClass avec jQuery

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

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

J'arrive à obtenir le comportement que je souhaite en utilisant animate() Cependant, les styles que j'anime doivent se trouver dans le code d'animation et sont donc séparés 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. S'anime en douceur entre le rouge et le bleu.
  2. Il n'y a pas de "surproduction" d'animation lorsque l'utilisateur déplace rapidement sa souris dans la division et en dehors de celle-ci.
  3. Si l'utilisateur déplace sa souris vers l'extérieur ou vers l'intérieur alors que l'animation est toujours en cours, le passage entre l'état actuel "à mi-chemin" et le nouvel état "objectif" se fait correctement.

Mais comme les changements de style sont définis dans animate() Je dois modifier les valeurs de style à cet endroit, et je ne peux pas simplement faire pointer la feuille de style vers moi. Cette "fragmentation" de l'endroit où les styles sont définis 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});
  });

Cela répond aux propriétés 1 et 2 de mes exigences initiales, mais la propriété 3 ne fonctionne pas.

Je comprends la raison de ce choix :

Lorsque vous animez addClass() et removeClass() jQuery ajoute un style temporaire à l'élément, puis incrémente les valeurs appropriées jusqu'à ce qu'elles atteignent les valeurs de la classe fournie, et c'est seulement à ce moment-là qu'il ajoute/supprime réellement la classe.

C'est pourquoi je dois supprimer l'attribut de style, sinon, si l'animation est arrêtée à mi-chemin, l'attribut de style resterait et écraserait de façon permanente les valeurs de la classe, car les attributs de style d'une balise ont plus d'importance que les styles de classe.

Cependant, lorsque l'animation est à moitié terminée, la nouvelle classe n'a pas encore été ajoutée, et donc, avec cette solution, la couleur saute à la couleur précédente lorsque l'utilisateur déplace sa souris avant la fin de l'animation.


Ce que je souhaite idéalement, c'est pouvoir faire quelque chose comme ceci :

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

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

1 votes

Quelles versions d'IE devez-vous prendre en charge ? Seriez-vous satisfait d'IE9 ? Ou devez-vous supporter une version inférieure ?

1 votes

Je ne me soucie pas du tout de l'IE pour être honnête. Tout ceci a été testé avec les navigateurs webkit uniquement (safari/chrome).

0 votes

Comment getClassContent ressemble à quoi ?

330voto

tw16 Points 12318

Puisque vous ne vous souciez pas d'IE, pourquoi ne pas utiliser des transitions css pour fournir l'animation et jQuery pour changer les classes. Exemple concret : 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 votes

Depuis le 2015-06-12, ceci est supporté dans - IE 10+ - Chrome 26+ - FireFox 16+ - Safari 6.1+ - Opera 12.1+ -webkit, -moz, -o n'est nécessaire que pour les navigateurs encore plus anciens. Vous pouvez probablement les laisser de côté pour gagner de la place.

3 votes

@clst, je préfère la rétrocompatibilité avec les anciens navigateurs à l'économie de quelques octets d'espace.

101voto

Omar Tariq Points 1206

Une autre solution (mais elle nécessite jQueryUI comme l'a fait remarquer Richard Neil Ilagan dans les commentaires) :-.

addClass, removeClass et toggleClass acceptent également un second argument : la durée du passage d'un état à l'autre.

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

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

30 votes

Notez que cela nécessite l'utilisation de jQuery UI. jQuery ne prend pas en charge l'interpolation des animations pour les éléments suivants xxxClass() fonctions.

0 votes

Richard Neil Ilagan : Merci de le signaler. Ce point m'a vraiment échappé.

4 votes

Pouvez-vous m'indiquer le fichier à télécharger et à inclure dans le fichier .html afin que je puisse utiliser jQueryUI uniquement pour les éléments suivants xxxClass l'animationweening de cette façon ?

38voto

by0 Points 1903

Vous pouvez utiliser l'interface utilisateur de Jquery. switchClass Voici un exemple :

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

Ou voyez ceci jsfiddle .

1 votes

-1. Vous n'avez pas respecté les restrictions 1, 2 et 3 que j'ai énumérées dans le message original. Plus précisément, switchClass gère mal les exigences 2 et 3.

13voto

Patrick Ludewig Points 63

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

2voto

Anurag Points 325

Bien que la question soit assez ancienne, j'ajoute des informations qui ne sont pas présentes 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, l'utilisation de la bonne combinaison de paramètres avec la fonction devrait aider. Par exemple, stop(true,true) ou stop(true,false), car cela affecte les animations en attente.

Le lien suivant présente une démo qui montre les différents paramètres disponibles avec stop() et comment ils diffèrent de finish().

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

Bien que l'OP n'ait pas eu de problèmes en utilisant JqueryUI, ceci est pour les autres utilisateurs qui peuvent rencontrer des scénarios similaires mais ne peuvent pas utiliser JqueryUI/doivent supporter IE7 et 8 également.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X