I've found some undesired, at least for me, behaviour when the route changes. In the step 11 of the tutorial http://angular.github.io/angular-phonecat/step-11/app/#/phon
None of the answer provided solved my issue. I am using an animation between views and the scrolling would always happen after the animation. The solution I found so that the scrolling to the top happen before the animation is the following directive:
yourModule.directive('scrollToTopBeforeAnimation', ['$animate', function ($animate) {
return {
restrict: 'A',
link: function ($scope, element) {
$animate.on('enter', element, function (element, phase) {
if (phase === 'start') {
window.scrollTo(0, 0);
}
})
}
};
}]);
I inserted it on my view as follows:
<div scroll-to-top-before-animation>
<div ng-view class="view-animation"></div>
</div>
A little late to the party, but I've tried every possible method, and nothing worked correctly. Here is my elegant solution:
I use a controller that governs all my pages with ui-router. It allows me to redirect users who aren't authenticated or validated to an appropriate location. Most people put their middleware in their app's config, but I required some http requests, therefore a global controller works better for me.
My index.html looks like:
<main ng-controller="InitCtrl">
<nav id="top-nav"></nav>
<div ui-view></div>
</main>
My initCtrl.js looks like:
angular.module('MyApp').controller('InitCtrl', function($rootScope, $timeout, $anchorScroll) {
$rootScope.$on('$locationChangeStart', function(event, next, current){
// middleware
});
$rootScope.$on("$locationChangeSuccess", function(){
$timeout(function() {
$anchorScroll('top-nav');
});
});
});
I've tried every possible option, this method works the best.
The problem is that your ngView retains the scroll position when it loads a new view. You can instruct $anchorScroll
to "scroll the viewport after the view is updated" (the docs are a bit vague, but scrolling here means scrolling to the top of the new view).
The solution is to add autoscroll="true"
to your ngView element:
<div class="ng-view" autoscroll="true"></div>
FYI for for anyone coming across the problem described in the title (as I did) who is also using the AngularUI Router plugin...
As asked and answered in this SO question, the angular-ui router jumps to the bottom of the page when you change routes.
Can't figure out why page loads at bottom? Angular UI-Router autoscroll Issue
However, as the answer states, you can turn off this behavior by saying autoscroll="false"
on your ui-view
.
For example:
<div ui-view="pagecontent" autoscroll="false"></div>
<div ui-view="sidebar" autoscroll="false"></div>
http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-view
I have finally gotten what I needed.
I needed to scroll to the top, but wanted some transitions not to
You can control this on a route-by-route level.
I'm combining the above solution by @wkonkel and adding a simple noScroll: true
parameter to some route declarations. Then I'm catching that in the transition.
All in all: This floats to the top of the page on new transitions, it doesn't float to the top on Forward
/ Back
transitions, and it allows you to override this behavior if necessary.
The code: (previous solution plus an extra noScroll option)
// hack to scroll to top when navigating to new URLS but not back/forward
let wrap = function(method) {
let orig = $window.window.history[method];
$window.window.history[method] = function() {
let retval = orig.apply(this, Array.prototype.slice.call(arguments));
if($state.current && $state.current.noScroll) {
return retval;
}
$anchorScroll();
return retval;
};
};
wrap('pushState');
wrap('replaceState');
Put that in your app.run
block and inject $state
... myApp.run(function($state){...})
Then, If you don't want to scroll to the top of the page, create a route like this:
.state('someState', {
parent: 'someParent',
url: 'someUrl',
noScroll : true // Notice this parameter here!
})
Simple Solution, add scrollPositionRestoration
in the main route module enabled.
Like this:
const routes: Routes = [
{
path: 'registration',
loadChildren: () => RegistrationModule
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes,{scrollPositionRestoration:'enabled'})
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }