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

后端 未结 18 2074
北恋
北恋 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:40

    All of the answers above break expected browser behavior. What most people want is something that will scroll to the top if it's a "new" page, but return to the previous position if you're getting there through the Back (or Forward) button.

    If you assume HTML5 mode, this turns out to be easy (although I'm sure some bright folks out there can figure out how to make this more elegant!):

    // Called when browser back/forward used
    window.onpopstate = function() { 
        $timeout.cancel(doc_scrolling); 
    };
    
    // Called after ui-router changes state (but sadly before onpopstate)
    $scope.$on('$stateChangeSuccess', function() {
        doc_scrolling = $timeout( scroll_top, 50 );
    
    // Moves entire browser window to top
    scroll_top = function() {
        document.body.scrollTop = document.documentElement.scrollTop = 0;
    }
    

    The way it works is that the router assumes it is going to scroll to the top, but delays a bit to give the browser a chance to finish up. If the browser then notifies us that the change was due to a Back/Forward navigation, it cancels the timeout, and the scroll never occurs.

    I used raw document commands to scroll because I want to move to the entire top of the window. If you just want your ui-view to scroll, then set autoscroll="my_var" where you control my_var using the techniques above. But I think most people will want to scroll the entire page if you are going to the page as "new".

    The above uses ui-router, though you could use ng-route instead by swapping $routeChangeSuccess for$stateChangeSuccess.

提交回复
热议问题