Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

ngRepeat leaves stale items when there is a css transition on the element and angular-animate is loaded #5376

Closed
damonf opened this issue Dec 12, 2013 · 8 comments
Assignees
Milestone

Comments

@damonf
Copy link

damonf commented Dec 12, 2013

Hi,

I'm using angular 1.2.4 and noticed that ngRepeat leaves stale items when a there is a css transition on the repeated element in IE10. It only started happening after i included angular-animate.

and here's the fiddle...
http://jsfiddle.net/RR5Tp/3/

Browsers: IE 10
Operating system: Windows 8.1

@matsko
Copy link
Contributor

matsko commented Dec 14, 2013

@ghost ghost assigned matsko Dec 14, 2013
@damonf
Copy link
Author

damonf commented Dec 14, 2013

Thanks, the stale items now disappear but they still appear for a fraction of a second.
http://jsfiddle.net/RR5Tp/4/

@matsko
Copy link
Contributor

matsko commented Dec 14, 2013

Alright, so this next bug is because of this: #5262

@matsko
Copy link
Contributor

matsko commented Dec 14, 2013

Is the flicker only showing up with IE10? I don't see it in Chrome.

@damonf
Copy link
Author

damonf commented Dec 14, 2013

Yep, its just IE10.

@matsko
Copy link
Contributor

matsko commented Dec 19, 2013

OK I figured out what's going on.

Your CSS transition declaration in invalid

The syntax for ease-in-out is only being understood by IE10, so to make it work with other browsers, have it in the format of PROPERTY DURATION EASE DELAY;

    -webkit-transition: color 0.08s ease-in-out;
    transition: color 0.08s ease-in-out;

Here's the cross-browser bug in action.
http://jsfiddle.net/RR5Tp/7/

That makes the flicker bug appear in Chrome and Firefox.

Now to deal with the flicker bug.

You have placed a transition on all a elements. When ngAnimate attempts to animate them it reads the transition value and in this case it finds something (0.08s). So it waits for that amount of time being animating and since nothing happens we get stale items. Since I mentioned the fix before (which is now in master) the items don't hang around, but there is still a flicker.

To deal with the flicker you can either:

  1. Override the .ng-animate property on the link tag and set transition:none; and -webkit-transition:none to make the flicker go away for link elements that are rendered by ngAnimate (on a repeater for example). There is no need to use the other transition properties. Just use transition and the webkit version. You can also specify specifically for .ng-enter, .ng-leave or .ng-move.

Here's a working example:
http://jsfiddle.net/RR5Tp/6/

  1. Wait for this commit to get in (today or tomorrow): feat(ngAnimate): provide configuration support to match specific className values to trigger animations #5448 which allows you specific a class pattern to match elements that will be animated. So if you set something like:
$animateProvider.classNameFilter(/animated/);

Then your links won't flicker or animate at all unless you pass in a .animated class to the class attribute on the link element.

Here's the fix in action.
http://jsfiddle.net/RR5Tp/9/

@matsko
Copy link
Contributor

matsko commented Dec 19, 2013

For now there is no automatic way to see if the element will actually animate during a event that ngAnimate starts. If we know that a style has changed (during the first CSS class) or will change (during the second CSS class) then we know for sure that an animation will kick off and we can open the space for that animation to close. The only for sure way to find this out is to make a deep copy of the content returned from window.getComputedStyle.

So

var node = element[0]; //break out of jquery
var styles0 = angular.copy(window.getComputedStyle(node));
node.className += ' ng-enter';
var styles1 = angular.copy(window.getComputedStyle(node));

var isDifferent = !equals(styles0, styles1);
node.className += ' ng-enter-active';
isDifferent = isDifferent || !equals(styles1, styles2);

if(isDifferent) {
  //do the animation
}

This would 100% eliminate bugs like the link bug, but it would entirely cripple the browser. There is no way we can cache this since the CSS selector pointing to the CSS is unknown and it could change at any point (CSS classes on parent elements changing or media queries). So we can't do that for now.

@matsko
Copy link
Contributor

matsko commented Dec 19, 2013

Closing this for now since there is no full fix, but if you use any of the two workarounds that I mentioned then you should be good.

@matsko matsko closed this as completed Dec 19, 2013
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants