8

For example:

A user scrolls down on view A;

Then the user clicks on a link, which takes the user to view B;

The view is changes, but the user's vertical location remains lthe same, and must scroll manually to the top of the screen.

Is it an angular bug?

I wrote a small workaround that uses jquery to scroll to the top; but I don't find the correct event to bind it to.

edit after seeing the comment:

How and WHEN do i pull myself to the top? i'm using jquery but the $viewContentLoaded event is too soon (the method runs, but the page doesn't scroll at that time)

Berry Tsakala
  • 15,313
  • 12
  • 57
  • 80
  • Probably you have fixed height or something. Changing the view angular removes content from ng-view and replace it with new content. For a moment ng-view's height == 0. So if you stay on the bottom of the page it means that page has no reason to pull you back to the top (no height change). – Pawel Uchida-Psztyc Jun 01 '14 at 14:42
  • You can wrap your scrolling code into a `$timeout` with a very short timeout, like 100ms. – Tong Shen Jun 01 '14 at 15:10

3 Answers3

22

The solution is to add autoscroll="true" to your ngView element:

<div class="ng-view" autoscroll="true"></div>

https://docs.angularjs.org/api/ngRoute/directive/ngView

Adriano Resende
  • 2,549
  • 1
  • 30
  • 34
9

Angular doesn't automatically scroll to the top when loading a new view, it just keeps the current scroll position.

Here is the workaround I use:

myApp.run(function($rootScope, $window) {

  $rootScope.$on('$routeChangeSuccess', function () {

    var interval = setInterval(function(){
      if (document.readyState == 'complete') {
        $window.scrollTo(0, 0);
        clearInterval(interval);
      }
    }, 200);

  });
});

Put it in your bootstrap (usually called app.js).

It's a pure javascript solution (it's always better not to use jQuery if it's easy).

Explanation: The script checks every 200ms if the new DOM is fully loaded and then scrolls to the top and stops checking. I tried without this 200ms loop and it sometimes failed to scroll because the page was just not completely displayed.

Guilhem Soulas
  • 1,975
  • 2
  • 18
  • 30
  • I would like to add some more to your answear: First of all `$routeChangeSuccess` is fired only if you are using the default router, you could be listening also to `$viewContentLoaded` or `$stateChangeSuccess` if you have some kind of custom navigation, Also if you are minifing your code `.run(function($rootScope, $window) {` should be called like this: `.run([ "$rootScope", "$window",function($rootScope, $window) {` Both the issues took me quite some time to realize so i hope this helps others (you might want to update your answear with those info @guilhem) – Yuri Scarbaci Oct 01 '18 at 11:26
1

It seems that you understand why the problem is happening based on @jarrodek's comment.

As for a solution, you could either follow @TongShen's solution of wrapping your function in a $timeout or you can put the function call within the partial that you're loading.

<!-- New partial-->
<div ng-init="scrollToTop()">

</div>

If you view change is fired after a click event, you could also put the function call on that element. Just comes down to timing though. Just depends on how things are set up.

EnigmaRM
  • 7,523
  • 11
  • 46
  • 72