désactiver nganimate pour certains éléments

96

J'utilise le module ngAnimate, mais tous mes ng-if, ng-showetc, sont touchés par cela, je veux levier ngAnimate pour certains éléments sélectionnés. Pour les performances et quelques bugs dans les éléments qui s'affichent et se cachent très rapidement.

Merci.

drtobal
la source
1
Ajoutez un exemple de code du problème.
cheekybastard
L'un des problèmes est que ngAnimate force display:blocksur tous vos répéteurs:ng-hide-add-active, .ng-hide-remove { display: block!important; }
Somatik
La meilleure question à poser serait "comment puis-je définir mon CSS pour que ngAnimate fonctionne correctement pour les éléments qui sont cachés sans terminer une boucle d'animation complète". La meilleure réponse est de Chris Barr ci-dessous.
Eric

Réponses:

53

Ajoutez simplement ceci à votre CSS. Il vaut mieux que ce soit la dernière règle:

.no-animate {
   -webkit-transition: none !important;
   transition: none !important;
}

puis ajoutez no-animateà la classe d'élément que vous souhaitez désactiver. Exemple:

<div class="no-animate"></div>
David Addoteye
la source
2
Si vous utilisez sass, vous n'avez pas besoin du "-webkit-transition: none! Important;"
Marwen Trabelsi
15
Veuillez noter que cette réponse est fausse car ELLE INTERDIT TOUTES LES ANIMATIONS, pas seulement celles qui sont gérées par Angular.
stackular
1
L'as tu essayé? laissez-moi voir un échantillon de votre code. Cela fonctionne pour moi et pour plus de six personnes qui l'ont approuvé
David Addoteye
2
J'ai ajouté une .no-animate, .no-animate-children *règle pour couvrir les enfants, etc.
Kimball Robinson
1
@DavidAddoteye cette solution n'est pas viable si vous avez un ng-show ou ng-if sur un élément avec transition .. Je veux dire .. si j'ai un spinner de chargeur qui n'apparaît que pendant la demande http et disparaît lorsque la demande est résolue, en ajoutant cette classe n'entraînera aucune animation du tout!, la réponse de Michael est correcte, mais trop fastidieuse à implémenter, et vous devriez essayer d'éviter les sélecteurs css dans les contrôleurs. Créer une directive est OK, mais en regardant la réponse de Blowsie, vous constaterez que l'équipe AngularJS a déjà fourni un moyen flexible de résoudre ce problème;)
edrian
106

Si vous souhaitez activer les animations pour des éléments spécifiques (au lieu de les désactiver pour des éléments spécifiques), vous pouvez utiliser $ animateProvider pour configurer des éléments avec un nom de classe particulier (ou regex) à animer.

Le code ci-dessous activera les animations pour les éléments qui ont la angular-animateclasse:

var myApp = angular.module("MyApp", ["ngAnimate"]);
myApp.config(function($animateProvider) {
  $animateProvider.classNameFilter(/angular-animate/);
})

Voici un exemple de balisage qui inclut la angular-animateclasse pour activer les animations:

<div ng-init="items=[1,2,3,4,5,6,7,8,9]">
  <input placeholder="Filter with animations." ng-model="f" /> 
  <div class="my-repeat-animation angular-animate" ng-repeat="item in items | filter:f track by item" >
    {{item}}
  </div>
</div>

Exemple de Plunker emprunté et modifié à partir de ce blog où seul le premier filtre a des animations (en raison de la angular-animateclasse).

Veuillez noter que j'utilise angular-animatecomme exemple et qu'il est entièrement configurable en utilisant la .classNameFilterfonction.

Gloopy
la source
5
Tu as sauvé ma journée. Merci beaucoup
gustavohenke
C'est la solution la plus élégante car elle nécessite une option pour les animations et les éléments animés sont clairement différenciés des autres par le nom de la classe.
Nikola M.
2
Cela devrait être la solution acceptée. Fonctionne parfaitement et m'a sauvé la journée!
9
utilisez /^(?:(?!ng-animate-disabled).)*$/regex pour désactiver l'annimation avec la ng-animate-disabledclasse.
IcanDivideBy0
Excellente solution! J'ai un tableau paginé avec 20 lignes par page. Un tiers du temps pour changer de page était consommé par le navigateur traitant les classes d'animation css qui n'étaient même pas utilisées.
Kevin
81

Il existe deux façons de supprimer les animations dans AngularJS si vous avez le module ngAnimate en tant que dépendance de votre module:

  1. Désactivez ou activez l'animation globalement sur le service $ animate:

    $animate.enabled(false);
  2. Désactivez les animations pour un élément spécifique - ce doit être l'élément pour lequel angular ajoutera les classes css animationstate (par exemple ng-enter, ...)!

    $animate.enabled(false, theElement);

À partir de la version Angular 1.4, vous devez inverser les arguments:

$animate.enabled(theElement, false);

Documentation pour$animate .

Michael
la source
2
Cela ne fonctionne pas sur des éléments spécifiques comme prévu. Si je désactive les animations globalement puis que je les active sur un élément particulier, cela ne fonctionne pas.
Kushagra Gour
1
Cette réponse doit être supprimée ou modifiée pour spécifier la version d'Angular sur laquelle elle fonctionne réellement. Pour 1.2.10, cela ne fonctionne certainement pas pour activer de manière sélective l'animation pour certains éléments, ce qui est tout l'objet de la question AFAICT.
Trindaz
Est-ce que quelqu'un sait si l'option 2 fonctionne sur la version 1.2.25?
khorvat le
1
En regardant la documentation ( docs.angularjs.org/api/ng/service/$animate ), il semble que l '«élément» soit le premier paramètre à être passé à la fonction activée.
DanielM
49

Pour désactiver ng-animate pour certains éléments, en utilisant une classe CSS, qui suit le paradigme Angular animate, vous pouvez configurer ng-animate pour tester la classe en utilisant regex.

Config

    var myApp = angular.module("MyApp", ["ngAnimate"]);
    myApp.config(function($animateProvider) {
        $animateProvider.classNameFilter(/^(?:(?!ng-animate-disabled).)*$/);
    })

Usage

Ajoutez simplement la ng-animate-disabledclasse à tous les éléments que vous voulez ignorer par ng-animate.


Crédit http://davidchin.me/blog/disable-nganimate-for-selected-elements/

Blowsie
la source
7
Je pense que c'est la manière la plus correcte de filtrer le comportement ngannimate!
edrian
6
Cela valait la peine de faire défiler cette réponse.
Jossef Harush
Je peux confirmer qu'avec la dernière version d'AngularJS, c'est certainement la meilleure solution au problème.
Adam Reis
44

merci, j'ai écrit une directive que vous pouvez placer sur l'élément

CoffeeScript:

myApp.directive "disableAnimate", ($animate) ->
  (scope, element) ->
    $animate.enabled(false, element)

JavaScript:

myApp.directive("disableAnimate", function ($animate) {
    return function (scope, element) {
        $animate.enabled(false, element);
    };
});
user1750709
la source
C'est une approche assez astucieuse, il n'est pas toujours clair comment accéder à l'objet élément, et avec certaines des autres approches, j'ai peur d'encombrer mes contrôleurs avec Javascript en référençant dur un ou plusieurs éléments définis dans un modèle . Cela ressemble à une grande séparation des préoccupations, bravo!
Mattygabe
2
L'ordre des paramètres est inversé dans $ animate.enabled, si quelqu'un se demande pourquoi cela désactive toutes les animations ng. Fonctionne comme un charme si vous utilisez$animate.enabled(element,false);
gss
Toutes mes excuses, je vois que cela s'applique uniquement à 1.4.x +, le code ci-dessus est correct pour les versions précédentes.
gss
19

J'ai trouvé que $animate.enabled(false, $element);cela fonctionnera pour les éléments qui utilisent ng-showou ng-hidemais cela ne fonctionnera pas pour les éléments qui utilisent ng-ifpour une raison quelconque! La solution que j'ai fini par utiliser était de tout faire en CSS, ce que j'ai appris de ce fil sur GitHub .

CSS

/* Use this for transitions */
.disable-animations.ng-enter,
.disable-animations.ng-leave,
.disable-animations.ng-animate {
  -webkit-transition: none !important;
  transition: none !important;
}

/* Use this for keyframe animations */
.disable-animations.ng-animate {
  -webkit-animation: none 0s;
  animation: none 0s;
}

SCSS

.disable-animations {
  // Use this for transitions
  &.ng-enter,
  &.ng-leave,
  &.ng-animate {
    -webkit-transition: none !important;
    transition: none !important;
  }
  // Use this for keyframe animations
  &.ng-animate {
    -webkit-animation: none 0s;
    animation: none 0s;
  }
}
CBarr
la source
Mon cas était qu'avec ngAnimate chargé, une classe comme .loading.ng-hide resterait à l'écran jusqu'à ce qu'une boucle d'animation complète soit terminée. C'est la réponse la plus claire, car il s'agit essentiellement de fournir la bonne configuration à ngAnimate et de l'utiliser normalement. Ceci est préférable à une mauvaise configuration, puis à sa désactivation. Alors +1 pour vous, j'aimerais pouvoir donner plus pour égaliser le score ici.
Eric
C'est la réponse la plus délicate. Le faire avec css est mieux que de jouer avec js.
manas
Veuillez regarder la réponse @Blowsie, c'est la façon la plus générique et la plus correcte de gérer cela
edrian
3

Je ne veux PAS utiliser ngAnimate sur mes ng-if, donc ce serait ma solution:

[ng-if] {
  .ng-enter, .ng-leave, .ng-animate {
    -webkit-transition: none !important;
    transition: none !important;
  }
}

Publiez simplement ceci comme une autre suggestion!

Rue Betty
la source
2

J'ai une liste dont le premier liest caché en utilisant ng-hide="$first". L'utilisation ng-enterentraîne l' liaffichage pendant une demi-seconde avant de disparaître.

Basé sur la solution de Chris Barr, mon code ressemble maintenant à ceci:

HTML

<ol>
    <li ng-repeat="item in items"
        ng-hide="$first"
        ng-class="{'no-animate' : $first}">
    </li>
</ol>

CSS

.no-animate.ng-enter,
.no-animate.ng-leave,
.no-animate.ng-animate {
        transition: none !important; /* disable transitions */
        animation: none 0s !important; /* disable keyframe animations */
}

li.ng-enter {
    opacity: 0;
    transition: opacity 0.3s ease-out;
}
li.ng-enter-active {
    opacity: 1;
}

/* I use Autoprefixer. If you don't, please include vendor prefixes. */
Robro
la source
0

Je sais que c'est une réponse différée, mais ici, nous utilisons dans MainController:

// disable all animations
$animate.enabled(false);

Mais le problème est que lorsque nous désactivons toutes les animations, les ui-select sont configurés sur opacity: 0.

Il est donc nécessaire de définir l'opacité sur 1 en utilisant CSS:

.ui-select-choices {
    opacity: 1 !important;
}

Cela définira correctement l'opacité et le ui-select fonctionnera.

David Branco
la source