24

I am having an odd, safari-only scrolling behavior using AngularJS.

Whenever the user flips between pages, the pages are being changed as if they are AJAX. I understand they are in AngualrJS, but the resulting behavior is that the browser does not scroll to top when the user switches pages.

I've tried to force the browser to scroll to top whenever a new controller is being used, but it does not seem to do anything.

I'm running the following JS at the top of every controller:

document.body.scrollTop = document.documentElement.scrollTop = 0;

This is also a Safari-only bug, every other browser will scroll to top when the page changes. Has anyone encountered a similar issue or think of a better way to resolve it?

Neil
  • 2,509
  • 7
  • 32
  • 47
  • can you please post more code, such as the controller data, maybe the config setup of your routeProvider... etc – David Chase Aug 14 '13 at 12:26

9 Answers9

51

$window.scrollTo(0,0) will scroll to the top of the page.

I just found a nice plugin (pure angularJS) that supports animations also:

https://github.com/durated/angular-scroll

Alex C
  • 1,334
  • 2
  • 18
  • 41
  • 5
    I know it may be obvious for intermediate/advanced AngularJS devs, but remember to AngularJS beginners (like myself): don't forget to add ```$window``` reference on your controller, otherwise it won't work. – Nighto Oct 10 '14 at 23:22
  • 1
    As an FYI, although it is clear in the README file, the mentioned repository has moved to [https://github.com/oblador/angular-scroll](https://github.com/oblador/angular-scroll) – Chris Brown Feb 15 '16 at 17:27
19

you can use this:

.run(["$rootScope", "$window", '$location', function($rootScope, $window,  $location) {

    $rootScope.$on('$routeChangeStart', function(evt, absNewUrl, absOldUrl){
        $window.scrollTo(0,0);    //scroll to top of page after each route change
}}])

or for tab switches you can use the $window.scrollTo(0,0); in your controller

danikoren
  • 4,191
  • 7
  • 34
  • 33
14

Have you tried using $anchorScroll()? it's documented here.

The WebMacheter
  • 1,776
  • 1
  • 20
  • 31
  • 17
    anchorScroll is for scrolling to the specefied element, if you just want to scroll to the top of the page I think $window.scrollTo(0, 0) should be used. – nacholibre Jun 09 '14 at 08:17
  • 19
    I found this answer while searching for a solution: http://stackoverflow.com/a/24549173/1578861 Adding autoscroll="true" to my ngView element worked for me:
    – nostopbutton Aug 06 '14 at 01:31
  • There's another answer to this question that may be more appropriate for many: http://stackoverflow.com/a/21734337/199712 – Jason Swett May 09 '15 at 15:04
3

I got the same problem while using AngularJS in a Cordova App. In a normal Browser or on Android i have no trouble but on ios i get the same behavior as discribed by Neil.

The AngularJS documentation on $anchorScroll is not that great so i thought to post this link which helped me way more:

http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html

Nico
  • 101
  • 1
  • 6
3

You can use $anchorScroll

$scope.gotoTop = function (){
  // set the location.hash to the id of
  // the element you wish to scroll to.
  $location.hash('top');

  // call $anchorScroll()
  $anchorScroll();
};
Fizer Khan
  • 88,237
  • 28
  • 143
  • 153
2

Like @nonstopbutton said, adding autoscroll="true" to my ngView element worked for me too. I mention this here because it was a comment to an answer and it was not easy to see his reply.

More information here: https://stackoverflow.com/a/24549173/1578861

Community
  • 1
  • 1
ilovemedia
  • 21
  • 3
0

I'd a similar issue with Chrome. However, I don't know if any specific external library is causing this issue or otherwise.

However I wrote this piece of code at app level and it works.

 $rootScope.$on('$viewContentLoaded', function(){
                $window.scrollTo(0, 0);
            });
codebased
  • 6,945
  • 9
  • 50
  • 84
0

Call $window.scrollTo(0,0); after locationChangeSuccess event:

$rootScope.$on("$locationChangeSuccess",
function(event, current, previous, rejection) {
  $window.scrollTo(0,0);
});
Abel
  • 3,989
  • 32
  • 31
0

In the controller you can actually drop the $ from window and simply putwindow.scrollTo(0,0); without having to inject $window into the controller. It worked great for me.

AAW238
  • 104
  • 4