在AngularJS中从顶部(反向)无限滚动

时间:2012-12-07 00:30:39

标签: angularjs

我正在尝试进行反向无限滚动。我有一个评论列表,其中我收到最近10条评论,并希望用户能够滚动向上以检索下一个10 - 类似于FB,其中显示最近的评论与'获取上一个'链接,但通过滚动事件而不是链接。

我从http://jsfiddle.net/vojtajina/U7Bz9/开始,并尝试将其修改为反向无限滚动,很快就结束了这样的事情:

  function Main($scope, $timeout) {
    $scope.items = [];

    var counter = 0;
    $scope.loadMore = function() {
      // simulate an ajax request
      $timeout( function() {
        for (var i = 0; i < 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 < 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;
        }
      });
    };
  }]);
  ​

http://jsfiddle.net/digger69/FwWqb/2/

问题是,当检索到接下来的10个项目时,它们会被添加到列表的顶部,并且整个列表会重新呈现,并且列表中的项目将完全滚动到视图之外。在小提琴项目中,“40”位于顶部,当您滚动(略微向下)然后向上以触发滚动时,项目“90”位于顶部。我正在寻找一个好的策略,在渲染后将“40”保持在滚动区域的顶部。

注意:在小提琴中,我能够通过在滚动事件中保存顶部li并调用scrollIntoView()直到我添加超时来模拟ajax调用来使其工作。使用超时时,在请求返回并呈现新元素之前,顶部li将滚动到视图中:/

var top = elm.find("li")[0];
scope.$apply(attr.whenScrolled);
top.scrollIntoView();

2 个答案:

答案 0 :(得分:21)

你可以尝试这样的事情:http://jsfiddle.net/mNFmf/4/

这将滚动到div的底部:

$timeout(function() {
    raw.scrollTop = raw.scrollHeight;          
});    

这将使div不会滚动到列表中的第一项:

var sh = raw.scrollHeight
scope.$apply(attr.whenScrolled);
raw.scrollTop = raw.scrollHeight - sh;

<强>更新

要解决ajax请求问题,请尝试使用promises

http://jsfiddle.net/mNFmf/8/

加载器看起来像这样:

$scope.loadMore = function() {
  var deferred = $q.defer();

  // do ajax request here and after getting the result call:   
  deferred.resolve();

  return deferred.promise;
};

另一方面:

loadMore.then(function() { 
  /* do whatever you want after the ajax request has been fulfilled */ 
});

答案 1 :(得分:0)

你有没有解决过这个问题?我们在阅读和设置scrollTop方面做了一些魔术,但发现Safari在设置和阅读scrollTop方面有一些奇怪的时间问题,因为我们滚动到一个位置,然后查询新位置,Safari仍然有旧职位。