title: infinite scroll from the top (reverse) in AngularJS
body: <p>I am trying to do a reverse infinite scroll. I have a comment list where I receive the last 10 most recent comments and want the user to be able to scroll <em>up</em> to retrieve the next 10 - similar to FB where it shows the most recent comments with a 'get previous' link, but via scroll event rather than a link. </p>
  
  <p>I started with <a href="http://jsfiddle.net/vojtajina/U7Bz9/" rel="nofollow noreferrer">http://jsfiddle.net/vojtajina/U7Bz9/</a> and tried to modify it to a reverse infinite scroll and pretty quickly ended up with something like this:</p>
  
  <pre><code>  function Main($scope, $timeout) {
      $scope.items = [];
  
      var counter = 0;
      $scope.loadMore = function() {
        // simulate an ajax request
        $timeout( function() {
          for (var i = 0; i &lt; 5; i++) {
            $scope.items.unshift({id: counter});
            counter += 10;
          }}, 1000);
      };
  
      $scope.loadMore();
    }
  
    angular.module('scroll', []).directive('whenScrolled', ['$timeout', function($timeout) {
      return function(scope, elm, attr) {
        var raw = elm[0];
  
        $timeout(function() {
          raw.scrollTop = raw.scrollHeight;
        }, 1100);
  
        elm.bind('scroll', function() {
          // note: if test for &lt; 100 get into infinite loop due to 
          // the delayed render
          if (raw.scrollTop === 0) {
            var sh = raw.scrollHeight
            scope.$apply(attr.whenScrolled);
            // the items are not loaded and rendered yet, so
            // this math doesn't work
            raw.scrollTop = raw.scrollHeight - sh;
          }
        });
      };
    }]);
    ​
  </code></pre>
  
  <p><a href="http://jsfiddle.net/digger69/FwWqb/2/" rel="nofollow noreferrer">http://jsfiddle.net/digger69/FwWqb/2/</a></p>
  
  <p>The issue is that when the next 10 items are retrieved, they are added to the top of the list and the entire list re-renders, and the item that was at the of the list is completely scrolled out of view. In the fiddle item "40" is at the top and when you scroll (down slightly) and then up to trigger the scrolled, item "90" is at the top. I'm looking for a good strategy to keep "40" at the top of the scroll area after it has rendered.</p>
  
  <p>Note: In the fiddle I was able to get it to work by saving off the top li in the scroll event and calling scrollIntoView() <em>until</em> I added the timeout to simulate the ajax call. With the timeout the top li is scrolled into view before the request has come back and the new elements are rendered :/</p>
  
  <pre><code>var top = elm.find("li")[0];
  scope.$apply(attr.whenScrolled);
  top.scrollIntoView();
  </code></pre>