How to keep scroll position after refreshing in AngularJS


When you add some items to the beginning of ng-repeated collection (probably with unshift method), AngularJS would refresh the view and take your adorable scrollbar to the top of it. Sometimes it can be naughty behaviour to you. So I’ll show you how to fix this problem.

Example

Here is an example. If you want to try it, please take a look at jsFiddle.

📄index.html
<html ng-app="app">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
    <script src="app.js"></script>
  </head>
  <body ng-controller="ItemsCtrl" keep-scroll-position>
    <a href="" ng-click="loadPreviousItems()" ng-if="!loaded">Load Previous Items</a>
    <div ng-repeat="item in items">
      <div>{{item}}</div>
    </div>
  </body>
</html>
📄app.js
angular.module('app', [])

.controller('ItemsCtrl', function($scope) {
  $scope.items = [];

  for (var i=100; i < 200; i++) {
    $scope.items.push('item' + i);
  }

  $scope.loadPreviousItems = function() {
    var previousItems = [];
    for (var i=0; i < 100; i++) {
      previousItems.push('item' + i);
    }
    Array.prototype.unshift.apply($scope.items, previousItems);
    $scope.loaded = true;
  };
})

.directive('keepScrollPosition', function() {
  return function(scope, el, attrs) {
    scope.$watch(
      function() { return el[0].clientHeight; },
      function(newHeight, oldHeight) {
        console.debug('Height was changed', oldHeight, newHeight);
        el[0].scrollTop = newHeight - oldHeight;
      });
  };
});

It’s a quite simple solution, that is, just $watching scroll container’s height. The increase of height means that your collection items were added and all DOM have been manipulated by AnuglarJS. The rest is easy, All you need to do is take the scroll bar to where it was (newHeight - oldHeight).

I hope this could be of any help.

関連する記事


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください