Changing route doesn't scroll to top in the new page

后端 未结 18 1970
北恋
北恋 2020-11-29 15:11

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

相关标签:
18条回答
  • 2020-11-29 15:21

    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>
    
    0 讨论(0)
  • 2020-11-29 15:23

    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.

    0 讨论(0)
  • 2020-11-29 15:24

    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>
    
    0 讨论(0)
  • 2020-11-29 15:25

    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

    0 讨论(0)
  • 2020-11-29 15:25

    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!
    })
    
    0 讨论(0)
  • 2020-11-29 15:26

    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 { }
    
    0 讨论(0)
提交回复
热议问题