Search code examples
cssangularjssassng-animate

Remove an element that is in the middle of an animation in angularjs


I have an instance where I have 3 possible scrolling animations depending on the model. I am using ng-if to handle the removal of the elements that don't match the model conditions. My problem arises when the model changes. The element that matches the condition starts it's scrolling animation, but the previous one seems to be left behind until the animation is complete. Inspection of the elements does show that ng-leave and ng-enter are applied respectively.

How can I get the old animation that doesn't match the ng-if condition to hide immediately?

View

<div class='phrase' ng-if='status === "live"'>
    LIVE
</div>
<div class='phrase' ng-if='status === "pending"'>
    PENDING
</div>
<div class='phrase' ng-if='status === "finished"'>
    FINISHED
</div>

SCSS

.phrase {
text-align: center;
color: rgba(255,255,255, 0.7);
font-weight: bold;
position: absolute;
white-space: nowrap;
width: 100%;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
font-size: 12vw;
animation: slide 10s linear infinite;
animation-direction: reverse;

@keyframes slide {
  0% {
    transform:translate(-270%, -50%);
  }
  100% {
    transform:translate(50%, -50%);
  }
}

Solution

  • Well I went with the tear off the band aid approach and removed the element manually from the DOM when I was through with it.

    I'd be interested to hear other answers if you figure out a way around the ng-animate debacle.

    // in view

    <div class='phrase' id='live' ng-if='status === "live"'>
        LIVE
    </div>
    <div class='phrase' id='pending' ng-if='status === "pending"'>
        PENDING
    </div>
    <div class='phrase' id='finished' ng-if='status === "finished"'>
        FINISHED
    </div>
    

    // in controller

    // watched for condition, then remove element with id
    if($scope.status === "live"){
        angular.element(document.querySelector("#pending")).remove();
    }
    

    --- EDIT ---

    I used the advice from @Mark Clark and took a simpler approach. Binding the status once in the view was the way to go. In my case this worked great, but I could still see where trying to overcome ng-animate overriding ng-if could be an issue for others. It's an outlying case for sure.

    BEST ANSWER

    <div class='phrase'>
        {{status}}
    </div>