对某些元素禁用nganimate


96

我正在使用ngAnimate模块,但是所有我的ng-ifng-show等等都受此影响,我想将ngAnimate用于某些选定的元素。为了提高性能和显示和隐藏元素的速度非常快。

谢谢。


1
添加问题的一些示例代码。
cheekybastard 2014年

问题之一是ngAnimate display:block会对您的所有中继器产生作用:ng-hide-add-active, .ng-hide-remove { display: block!important; }
Somatik

要问的更好的问题是“如何定义我的CSS以使ngAnimate对于隐藏的元素正确工作而不完成完整的动画循环”。最佳答案来自下面的克里斯·巴尔。
埃里克

Answers:


53

只需将其添加到您的CSS中即可。最好是最后一条规则:

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

然后将其添加no-animate到要禁用的元素类中。例:

<div class="no-animate"></div>

2
如果您使用的是sass,则不需要“ -webkit-transition:none!important;”
Marwen Trabelsi 2015年

15
请注意,此答案是错误的,因为它会禁用所有动画,而不仅仅是Angular处理的动画。
堆积

1
你试过了吗?让我看看您的代码示例。它对我和超过六名批准它的人都有效
David Addoteye

2
我添加了.no-animate, .no-animate-children *覆盖儿童等的规则
Kimball Robinson

1
@DavidAddoteye如果您在具有过渡的元素上进行ng-show或ng-if时,此解决方案不可行。.我的意思是..如果我的加载程序微调器仅在http请求期间显示,而在请求解析时消失,则添加此类完全不会产生动画!,michael的回答还可以,但是实现起来过于繁琐,您应该尝试避免在控制器中使用css选择器。创建一个指令是可以的,但是查看Blowsie的答案,您会发现AngularJS团队已经提供了一种灵活的方法来解决此问题;)
edrian 2016年

106

如果要为特定元素启用动画(而不是为特定元素禁用动画),则可以使用$ animateProvider来配置具有特定类名(或正则表达式)的元素进行动画处理。

以下代码将为具有此类的元素启用动画angular-animate

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

以下是示例标记,其中包括angular-animate启用动画的类:

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

从此博客借来并修改了Plunker示例,其中只有第一个过滤器具有动画(由于具有angular-animate类)。

请注意,我angular-animate以示例为例,可以使用.classNameFilter函数完全对其进行配置。


5
你救了我的日子。非常感谢
gustavohenke 2014年

这是最优雅的解决方案,因为它需要选择动画,并且动画元素在类别名称上与其他元素明显不同。
Nikola M.

2
这应该是公认的解决方案。完美的作品,挽救了我的一天!

9
使用/^(?:(?!ng-animate-disabled).)*$/正则表达式禁用与ng-animate-disabled类的动画。
IcanDivideBy0

很好的解决方案!我有一个分页的表格,每页20行。浏览器处理甚至没有使用过的动画css类占用了三分之一的切换页面时间。
凯文(Kevin)

81

如果您将ngAnimate模块作为模块的依赖项,则可以通过两种方法在AngularJS中取消动画处理:

  1. 在$ animate服务上全局禁用或启用动画:

    $animate.enabled(false);
  2. 禁用特定元素的动画-这必须是该角度的元素,它将添加animationstate css类(例如ng-enter,...)!

    $animate.enabled(false, theElement);

从Angular 1.4版本开始,您应该反转参数:

$animate.enabled(theElement, false);

的文档$animate


2
这不适用于预期的特定元素。如果我全局关闭动画,然后在一个特定的元素上启用它,那么它将不起作用。
Kushagra Gour 2014年

1
应该删除或编辑此答案,以指定实际使用的Angular版本。对于1.2.10,它绝对不能选择性地为某些元素启用动画,这是AFAICT问题的全部要点。
Trindaz 2014年

有人知道选项2是否适用于1.2.25版本吗?
khorvat 2014年

1
仅查看文档(docs.angularjs.org/api/ng/service/$animate),似乎«element»是传递给已启用功能的第一个参数。
DanielM

49

要使用Angular animate范式的CSS类禁用某些元素的ng-animate,可以配置ng-animate以使用正则表达式测试该类。

设定档

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

用法

只需将ng-animate-disabled类添加到您要被ng-animate忽略的任何元素。


信用 http://davidchin.me/blog/disable-nganimate-for-selected-elements/


7
我认为这是过滤ngannimate行为的最正确方法!
edrian

6
值得滚动浏览此答案。
约瑟夫·哈鲁什

我可以确认,使用最新版本的AngularJS,这绝对是解决该问题的最佳方法。
亚当·雷斯

44

谢谢,我写了一条指令,您可以将其放置在元素上

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

这是一个非常漂亮的方法,并不总是很清楚如何访问元素对象,而在其他一些方法中,恐怕我会用Javascript硬引用模板中定义的一个或几个元素来弄乱我的控制器。 。感觉就像是担忧的分离,荣誉!
Mattygabe

2
如果有人想知道为什么禁用所有ng动画,则$ animate.enabled中的参数顺序相反。如果您使用的话,会像魅力一样工作$animate.enabled(element,false);
gss

抱歉,我看到这仅适用于1.4.x +,上面的代码对于以前的版本是正确的。
gss

19

我发现这$animate.enabled(false, $element);将对使用ng-show或的元素起作用,ng-hide但是对于出于某些原因的使用将不起作用ng-if!我最终使用的解决方案只是在CSS中完成所有操作,这是我从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;
  }
}

我的情况是,加载ngAnimate时,像.loading.ng-hide这样的类将保留在屏幕上,直到完成完整的动画循环为止。这是最干净的答案,因为它基本上只是将正确的配置提供给ngAnimate并正常使用。这比先配置错误然后禁用它更为可取。因此,为您+1,希望我能在这里给更多的贡献。
埃里克

这是最棘手的答案。用css进行处理比用js进行处理要好得多。
manas 2015年

请查看@Blowsie答案,这是处理此问题的更通用且正确的方法
edrian

3

希望使用ngAnimate我ng-if的,所以这将是我的解决方案:

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

只是将此发布为另一个建议!


2

我有一个列表,其中li使用隐藏了第一个ng-hide="$first"。在中使用ng-enter结果li显示半秒钟,然后消失。

基于克里斯·巴尔的解决方案,我的代码现在如下所示:

的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. */

0

我知道这是一个延迟回复,但是在这里我们在MainController中使用:

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

但是问题是,当我们禁用所有动画时,ui-select配置为 opacity: 0

因此,有必要使用CSS将不透明度设置为1:

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

这将正确设置不透明度,并且ui-select将起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.