desactivar nganimate para algunos elementos

96

Estoy usando el módulo ngAnimate, pero toda mi ng-if, ng-show, etc, se ven afectados por eso, quiero aprovechar ngAnimate para algunos elementos seleccionados. Por rendimiento y algunos errores en elementos que se muestran y ocultan muy rápidamente.

Gracias.

drtobal
fuente
1
Agregue un código de ejemplo del problema.
cheekybastard
Uno de los problemas es que ngAnimate fuerza display:blocken todos sus repetidores:ng-hide-add-active, .ng-hide-remove { display: block!important; }
Somatik
La mejor pregunta sería "¿cómo puedo definir mi CSS para que ngAnimate funcione correctamente para los elementos que están ocultos sin completar un ciclo de animación completo?". La mejor respuesta es de Chris Barr a continuación.
Eric

Respuestas:

53

Solo agregue esto a su CSS. Es mejor si es la última regla:

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

luego agregue no-animatea la clase de elemento que desea deshabilitar. Ejemplo:

<div class="no-animate"></div>
David Addoteye
fuente
2
Si está usando sass, no necesita el "-webkit-transition: none! Important;"
Marwen Trabelsi
15
Tenga en cuenta que esta respuesta es incorrecta porque DESHABILITA TODAS LAS ANIMACIONES, no solo las que maneja Angular.
stackular
1
¿Lo has probado? déjame ver una muestra de tu código. Funciona para mí y para más de seis personas que lo han aprobado
David Addoteye
2
Agregué una .no-animate, .no-animate-children *regla para cubrir a los niños, etc.
Kimball Robinson
1
@DavidAddoteye esta solución no es viable si tiene un ng-show o ng-if sobre un elemento con transición ... quiero decir ... si tengo un cargador giratorio que aparece solo durante la solicitud http y desaparece cuando se resuelve la solicitud, agregando ¡esta clase no dará como resultado ninguna animación !, la respuesta de Michael está bien, pero es demasiado tediosa de implementar, y debe intentar evitar los selectores css en los controladores. Crear una directiva está bien, pero al mirar la respuesta de Blowsie, encontrará que el equipo de AngularJS ya ha proporcionado una forma flexible de solucionar este problema;)
edrian
106

Si desea habilitar animaciones para elementos específicos (en lugar de deshabilitarlas para elementos específicos), puede usar $ animateProvider para configurar elementos con un nombre de clase particular (o expresión regular) para animar.

El siguiente código habilitará animaciones para elementos que tengan la angular-animateclase:

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

Aquí hay un marcado de ejemplo que incluye la angular-animateclase para habilitar animaciones:

<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>

Ejemplo de Plunker tomado y modificado de este blog donde solo el primer filtro tiene animaciones (debido a que tiene elangular-animate clase).

Tenga en cuenta que lo estoy usando angular-animatecomo ejemplo y es completamente configurable usando la .classNameFilterfunción.

Gloopy
fuente
5
Salvaste mi día. Muchas gracias
gustavohenke
Esta es la solución más elegante, ya que requiere optar por las animaciones y los elementos animados se diferencian claramente de otros por el nombre de la clase.
Nikola M.
2
Esta debería ser la solución aceptada. ¡Funciona perfecto y me salvó el día!
9
use /^(?:(?!ng-animate-disabled).)*$/regex para deshabilitar la anotación con ng-animate-disabledclase.
IcanDivideBy0
¡Gran solución! Tengo una tabla paginada con 20 filas por página. Un tercio del tiempo para cambiar de página lo consumía el navegador que procesaba las clases CSS de animación que ni siquiera se estaban utilizando.
Kevin
81

Hay dos formas en que puede deshabilitar animaciones en AngularJS si tiene el módulo ngAnimate como una dependencia de su módulo:

  1. Deshabilite o habilite la animación globalmente en el servicio $ animate:

    $animate.enabled(false);
  2. Deshabilite las animaciones para un elemento específico: este debe ser el elemento para que angular agregue las clases css de animationstate (por ejemplo, ng-enter, ...).

    $animate.enabled(false, theElement);

A partir de la versión Angular 1.4, debe invertir los argumentos:

$animate.enabled(theElement, false);

Documentación para$animate .

Miguel
fuente
2
Esto no funciona en elementos específicos como se esperaba. Si apago las animaciones globalmente y luego las habilito en un elemento en particular, no funciona.
Kushagra Gour
1
Esta respuesta debe eliminarse o editarse para especificar en qué versión de Angular realmente funciona. Para 1.2.10 definitivamente no funciona para habilitar selectivamente la animación para ciertos elementos, que es el punto central de la pregunta AFAICT.
Trindaz
¿Alguien sabe si la opción 2 está funcionando en la versión 1.2.25?
khorvat
1
Con sólo mirar la documentación ( docs.angularjs.org/api/ng/service/$animate ) parece que el «elemento» es el primer parámetro que se pasa a la función habilitada.
DanielM
49

Para deshabilitar ng-animate para ciertos elementos, usando una clase CSS, que sigue el paradigma animado de Angular, puede configurar ng-animate para probar la clase usando expresiones regulares.

Config

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

Uso

Simplemente agregue la ng-animate-disabledclase a cualquier elemento que desee que ng-animate ignore.


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

Blowsie
fuente
7
¡Creo que esta es la forma más correcta de filtrar el comportamiento ngannimate!
edrian
6
Valió la pena desplazarse por esta respuesta.
Jossef Harush
Puedo confirmar que con la última versión de AngularJS esta es definitivamente la mejor solución para el problema.
Adam Reis
44

gracias, escribí una directiva que puedes colocar en el elemento

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);
    };
});
usuario1750709
fuente
Este es un enfoque bastante ingenioso, no siempre está claro cómo acceder al objeto de elemento, y con algunos de los otros enfoques, me temo que estaría saturando mis controladores con Javascript haciendo referencia a uno o varios elementos definidos en una plantilla. . Esto se siente como una gran separación de preocupaciones, ¡felicitaciones!
Mattygabe
2
El orden de los parámetros se invierte en $ animate.enabled, si alguien se pregunta por qué esto deshabilita todas las animaciones ng. Funciona como un encanto si lo usa$animate.enabled(element,false);
gss
Disculpas, veo que solo se aplica a 1.4.x +, el código anterior es correcto para versiones anteriores.
gss
19

Descubrí que $animate.enabled(false, $element);funcionará para elementos que usan ng-showo, ¡ ng-hidepero no funcionará para elementos que usan ng-ifpor alguna razón! La solución que terminé usando fue hacerlo todo en CSS, que aprendí de este hilo en 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
fuente
Mi caso fue que con ngAnimate cargado, una clase como .loading.ng-hide permanecería en la pantalla hasta que se completara un ciclo de animación completo. Esta es la respuesta más limpia, porque básicamente solo alimenta la configuración correcta a ngAnimate y la usa normalmente. Esto es preferible a configurarlo incorrectamente y luego deshabilitarlo. Así que +1 para ti, desearía poder dar más para igualar el puntaje aquí.
Eric
Ésta es la respuesta más complicada. Hacerlo con css es mejor que jugar con js.
manas
Por favor, mire la respuesta de @Blowsie, esa es la forma más genérica y correcta de lidiar con esto
edrian
3

Yo no quiero usar ngAnimate en mis ng-if's, por lo que este sería mi solución:

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

¡Solo publico esto como otra sugerencia!

Betty St
fuente
2

Tengo una lista de la que lise oculta el primero con ng-hide="$first". El uso de ng-enterresultados en el que lise muestra durante medio segundo antes de desaparecer.

Basado en la solución de Chris Barr, mi código ahora se ve así:

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
fuente
0

Sé que es una respuesta retrasada, pero aquí usamos en MainController:

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

Pero el problema es que cuando deshabilitamos todas las animaciones, la interfaz de usuario está configurada para opacity: 0.

Entonces, es necesario establecer la opacidad en 1 usando CSS:

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

Esto establecerá correctamente la opacidad y la ui-select funcionará.

David Branco
fuente