Angular.js: ng-show / hide在正在设置动画的元素上延迟

创建于 2014-07-16  ·  17评论  ·  资料来源: angular/angular.js

如果您正在对诸如加载微调器之类的东西进行恒定的动画并且只想立即隐藏或显示它,则这不是预期的行为。

没有告诉这个元素是由ng-animate管理的,我只是希望正常的ng-show / hide立即发生,并且我认为正在进行的任何CSS动画都应该是无关紧要的。

小提琴: http :

取消选中“显示加载程序”,请注意,实际上要花几秒钟的时间。

我认为这是最近的更改,因为我们的加载程序在升级之前并未停留在我们的应用程序中。 我认为我们之前是1.12。

我对如何使用/不使用ng-animate的理解一定有所遗漏,对吗? 在这种情况下,我实际上不想使用它,但是如果我可以使用它来忽略该元素,那也将起作用。 绝对令人惊讶的行为。

ngAnimate broken expected use bug

最有用的评论

@ tole42这是解决方法:

.YourElementClass.ng-animate { -webkit-animation: none 0s; }

所有17条评论

ngAnimate很贪婪,因为它假定在任何触发器期间在元素上处于活动状态的所有关键帧/过渡代码都将通过ngAnimate进行动画处理。 因此,在这种情况下,尽管.loader与ngShow / ngHide没有任何关系,它仍然被当作有效的动画。

为了解决这个问题,当在元素上应用.ng-animate类时,

http://jsfiddle.net/PvS8k/4/

这是CSS继承的问题。 如果有一种更好的方法来检测样式,而不必完全依赖getComputedStyle,则可以避免这种怪癖。

@matsko我认为这种特殊情况实际上是回归。 如您在@SimpleAsCouldBe的插件或此插件http://plnkr.co/edit/5cfIXfNryNOzK66q9YWL?p=preview中所见,在1.2.17中,该元素不会立即消失,但在1.2.16中,它不会立即消失。做。 这很可能是由于https://github.com/angular/angular.js/commit/55b2f0e8620465559016b424967d90a86af597c0
我认为需要进一步检查。 至少在变更日志和文档中应该有关于此的注释。

感谢您的解决方法,它可以达到预期的效果。

两点。 一种是针对ng-show的,另一种是一般的。

ng-show +无限动画:

无限动画_really_是否应该延迟ng-show的隐藏? 我尝试计算秒数,但等待隐藏的时间并不总是4秒。 有时它的5或7 ...似乎有所不同。 同样,如果您再次打开和关闭复选框,它永远也不会隐藏。 我认为这是某个地方隐藏的实际错误。

哲学的

作为非贡献者,我没有太多发言权,但是对于这个库来说,选择退出不是正确的策略。 这只是如此惊人的神奇有JS库反应CSS规则..如果我必须与标签元素ng-animatable我会为此更加准备。

@SimpleAsCouldBe是的,我一直在想,也许最好是要求所有动画都具有animate-类前缀,这样ngAnimate才能加入动画中。

关于延迟,不是因为存在延迟,而是因为ngAnimate取消了无限部分,并且只运行了一次动画。 因此,将其隐藏时,它将等待2s * 1.5 = 3秒,然后运行超时检查并关闭动画。 因此,这是一个根本不应该存在的不必要的时间窗口-仅CSS样式检测受到高度限制。

@Narretz虽然您提供的提交可能会影响此特定示例,但实际上与回归没有任何关系。 这样做的原因是,修复程序在不同时间应用display:none值之前存在的.ng-hide样式。 但是,当前修复仅在完成所有动画后才应用(一旦删除了.ng-animate类)。

看看下面的演示。 查看.blue类的选择器有两套:一组有.ng-animate ,而没有。 尽管立即应用了.blue类,但是ngAnimate仍然认为动画是到期的,并且将在应用关闭超时之前等待3s (记住2s * 1.5)。 通常是2秒,但是不会触发animationend事件,因为元素上的实际动画(由于.loader )是无限的,并且不会被ng-class触发(或ng-show来显示上一个示例)。 因此,由于先前的错误修复,这不会生效。
http://jsfiddle.net/PvS8k/15/

最好使ngAnimate少一些天真,只有当animated-作为CSS前缀存在时才进行动画处理。

我认为,如果您愿意接受诸如选择动画处理之类的重大变革,那么它将为您带来不那么令人惊讶的开发人员体验。

您是否愿意使用像.ng-animate这样的特定角度前缀而不是普通的.animate前缀?

我也有同样的问题:
角度> = 1.2.17 http://jsfiddle.net/9krLr/17/
使用angular 1.2.16,一切都很好: http :

@ tole42这是解决方法:

.YourElementClass.ng-animate { -webkit-animation: none 0s; }

谢谢你的帮助。 解决方法不起作用:(
怎么了?
http://jsfiddle.net/9krLr/21/

据我所知,该小提琴中没有任何动画。 动画是Foundation库的一部分吗? 更直接的重新创建案例将使其更易于调试。 在我看来不一样。

我相信我看到了与@ tole42相同的问题。 当模块中包含ngAnimate时,如果您不希望对其进行动画处理,则标准ng-hide / ng-show功能对于基本情况将无法正常工作。 换句话说,当您在没有应用动画类的普通元素上使用ng-hide / ng-show时。

<div ng-hide="hideme">hide me</div>

如果要在该皮革上制作动画,可以执行以下操作:

<div ng-hide="hideme" class="myanimation">hide me</div>

在应用程序中,有些实例可能需要对显示/隐藏进行动画处理,而另一些实例中则不想进行动画处理。 在您不想设置动画的实例中,您不会使用任何自定义动画类来装饰显示/隐藏的元素。 在这种情况下,Angular只会将“ ng-hide”类添加到隐藏元素中。

如果您根本不在模块中包含ngAnimate,则此操作将按预期进行:该元素会立即消失。 但是,通过简单地包含ngAnimate,您将获得@ tole42发布的两个小提琴中显示的行为:在添加了“ ng-hide”类的元素实际上消失之前,有一个延迟。 如果您不打算在其上使用动画,它应该立即消失。

几个可行的解决方法是:

.ng-hide-add {
    transition: 0s linear all;
}

或者:

.ng-hide {
    display: none !important;
}

但是,在您只是试图以非动画方式隐藏某些东西的情况下,那些必需的东西似乎是不正确的。

只是为了跟进一些其他发现...

试图将问题归结为最简单的情况-显示/隐藏普通div-问题没有显现。

我在@ tole42发布的小提琴中注意到正在使用foundation.css,该示例确实显示了显示/隐藏输入字段的问题。 我的经验相似(使用输入字段查看问题清单),但是使用bootstrap.css。 仔细研究这两个css文件,它们都将css转换应用于输入字段。

那些css过渡似乎是真正的罪魁祸首,因为角动画会从中获取持续时间。 这就是在显示/隐藏这些元素时导致视觉延迟的原因,即使您并非故意尝试为该过渡设置动画。

因此,我认为这不一定是Angular应该尝试解决的问题。 与其他css库一起使用angular-animate更具副作用,该库可能具有一些您不期望的嵌入式css过渡!

花了很长时间来找出根本原因,但是最终找到一个有意义的理由是一件好事。

是的,这是ngAnimate的重要问题,但是由于缺乏对getComputedStyle的控制以及其他库中转换的级联,ngAnimate无法检测到这一点。

解决此问题的方法有两种:

1)覆盖.ng-animate类的样式:
http://jsfiddle.net/9krLr/27/

之所以对您不起作用,是因为缺乏CSS特异性。

2)使用$animateProvider.classNameFilter(regex) 。 在这种情况下,正则表达式将在所有ngAnimate触发的动画上放置一个硬块,并且仅当正则表达式与要动画化的元素上存在的className匹配时才允许动画发生。

哦,将配置放在提供程序中是一个不错的方法,我非常喜欢@matsko!

@pnutshellmenace感谢您的快速解决方案。 它挽救了我的一天。

我不明白这里的最终解决方案是什么。 @matsko说:

最好使ngAnimate少一些天真,只在有动画时设置动画-在某处作为CSS前缀存在

但是我看不到这样的实现。 我看了一下$animateProvider.classNameFilter(regex)但同样,我遇到的问题多于答案。 实现此目的的实际方法是什么?如果有多个适用的类名,该怎么办?

我看不出ngAnimate为什么要假设我要为所有动画设置动画。 总会有一些我不想设置动画的东西,而与其他方法相比,我现在不想动画的更多,这使得手动设置它们的样式以禁用过渡效果不吸引人。

编辑:找到了这个博客文章,使事情变得更加有意义...我将尝试一下: http :

编辑2:添加$animateProvider.classNameFilter(/enable-animate/);可行,但是在此过程中,我发现了一些有趣的行为:

我包括了一个第三方Angular模块的.js文件,该文件依赖于ngAnimate,并且某种程度上,这甚至导致在我自己的模块上触发动画。 ngAnimate是否以某种方式影响了父模块的作用域?

我希望使用$scope.$evalAsync();进行异步操作的答案。 效果很好。

此页面是否有帮助?
0 / 5 - 0 等级