Search code examples
angularjsbackangularjs-animationangularjs-view

Different animation when history.back() ist used


I've created a website based on AngularJS. Every page has it's own template and controller and is included via ng-view in the main layout.

But I have a problem with animations between different pages. I want them to fly in from the right (and to disappear to the left) if navigating forward, and vice versa (flying in from the left, disappearing to the right) when the user hits the back button of his browser or history.back() is triggered in the JS code.

How do I do this?

I've managed to define animations by assigning them to the classes ng-enter and ng-leave, but then they do not change when the back button is pressed, i.e. the last page enters from the right and not from the left side.

I also tried to define the backwards-animation as the default animation and changing the class of the ng-view element dynamically when I want to navigate forwards in order to use the correct animation, but to reset this temporary class I (think I) had to use a timer that simply resets it after X milliseconds (when the animation has finished). Unfortunately, this leads to bugs when the user presses back to quickly/during a forwards animation.


Solution

  • I managed to find a solution. You can see it online, or read the code

    The basic idea is this:

    • the back-animation is the default animation
    • whenever we want to animate forwards, this is done via a special function that changes the classnames of a container, so the forwards-animation is used
    • this change is undone once the old page is deleted from the DOM

    The last step is important: Do not use a timer or anything like that. When the browsers back button is pressed during a forwards animation, a timer won't notice that and the change of the classnames isn't undone.
    But when the button is pressed, the old page doesn't finish it's animation, it's instantly removed from the DOM, and this triggers the code that changes the classnames back.


    The most important parts of the code:

    Use this function to change the current page using a forwards animation:

    function animateForwards(callback) {
        $('#container').addClass("animation-forwards");
        $('#container').removeClass("animation-backwards");
        callback();
    }
    
    animateForwards(function () { $location.path("/newPage"); });
    

    This function undoes the change of the classnames once an old page is removed from the DOM:

    $("#container").bind(
      "DOMNodeRemoved",
      function(objEvent) {
        // Append event to log display.
        if ($(objEvent.target).hasClass('page')) {
          $('#container').removeClass("animation-forwards");
          $('#container').addClass("animation-backwards");
        }
      }
    );