AngularJS + Safari: Force page to scroll to top when pages switch

All we need is an easy explanation of the problem, so here it is.

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?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

$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

Method 2

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

Method 3

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

Method 4

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

Method 5

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();
};

Method 6

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

Method 7

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);
            });

Method 8

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

$rootScope.$on("$locationChangeSuccess",
function(event, current, previous, rejection) {
  $window.scrollTo(0,0);
});

Method 9

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.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply