【问题标题】:infinite scroll from the top (reverse) in AngularJS在AngularJS中从顶部(反向)无限滚动
【发布时间】:2012-12-07 00:30:39
【问题描述】:

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

我从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();

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    你可以试试这样的: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 */ 
    });
    

    【讨论】:

    • 感谢您的回复。好主意...但是我遇到的问题是 scope.$apply(attr.whenScrolled) 是一个ajax调用,因此当 raw.scrollTop = raw.scrollHeigh - 时尚未呈现新项目sh 运行。我将更新问题并进行演示。
    • 这救了我!!
    【解决方案2】:

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

    【讨论】:

    • 它一直在为我们工作——但我们的目标平台是移动的。注意:这个周末我刚看到这个 - github.com/BinaryMuse/ngInfiniteScroll
    • @digger69 我有兴趣(作为作者)知道这是否对你有用。
    • @BrandonTilley,嗨 Brandon,是否可以使用 ngInfiniteScroll 进行反向无限滚动?谢谢!
    猜你喜欢
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2013-11-24
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    相关资源
    最近更新 更多