将内容附加到列表时保持滚动位置(AngularJS)

Posted

技术标签:

【中文标题】将内容附加到列表时保持滚动位置(AngularJS)【英文标题】:Maintain the scroll position when prepending content to a list (AngularJS) 【发布时间】:2015-12-06 19:44:19 【问题描述】:

我一直在尝试使用ng-repeat 将一些项目添加到可滚动容器内的列表中,最近的项目应该位于列表的顶部。如果在添加内容时容器的滚动条不在最顶部,我还需要保持滚动位置。

这是我的解决方案,但我仍有问题。 angular 渲染 dom 中的前置项后总是闪烁。

var myApp = angular.module('myApp', []);

myApp.controller('MainCtrl', function($scope, $interval, $timeout) 
  $scope.items = [];
  $interval(function() 
    var item = 
      id: Math.random(),
      text: (new Date()).toString()
    ;
    $scope.items.unshift.apply($scope.items, [item]);

    var $container = $('.stream-container');
    var $topItem = $('.item:first');
    var oScrollTop = $container.scrollTop();
    var oOffset = $topItem.length ? $topItem.position().top : 0;

    $timeout(function() 
      // Executed after the dom has finished rendering
      if ($container.scrollTop() !== 0) 
        $container.scrollTop(oScrollTop + ($topItem.length ? $topItem.position().top : 0) - oOffset);
      
    );
  , 1000);
);
.stream-container 
  overflow-y: scroll;
  overflow-x: none;
  height: 100px;
  position: relative;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<body ng-app="myApp">
  <div class="stream-container" ng-controller="MainCtrl">
    <div class="stream">
      <div class="item" ng-repeat="item in items track by item.id"> item.text </div>
    </div>
  </div>
</body>

【问题讨论】:

【参考方案1】:

我找到了this post 并将$timeout 更改为$scope.$$postDigest。现在它按预期工作了。

var myApp = angular.module('myApp', []);

myApp.controller('MainCtrl', function($scope, $interval, $timeout) 
  $scope.items = [];
  $interval(function() 
    var item = 
      id: Math.random(),
      text: (new Date()).toString()
    ;
    $scope.items.unshift.apply($scope.items, [item]);

    var $container = $('.stream-container');
    var $topItem = $('.item:first');
    var oScrollTop = $container.scrollTop();
    var oOffset = $topItem.length ? $topItem.position().top : 0;

    $scope.$$postDigest(function() 
      // Executed after the dom has finished rendering
      if ($container.scrollTop() !== 0) 
        $container.scrollTop(oScrollTop + ($topItem.length ? $topItem.position().top : 0) - oOffset);
      
    );
  , 1000);
);
.stream-container 
  overflow-y: scroll;
  overflow-x: none;
  height: 100px;
  position: relative;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<body ng-app="myApp">
  <div class="stream-container" ng-controller="MainCtrl">
    <div class="stream">
      <div class="item" ng-repeat="item in items track by item.id"> item.text </div>
    </div>
  </div>
</body>

【讨论】:

以上是关于将内容附加到列表时保持滚动位置(AngularJS)的主要内容,如果未能解决你的问题,请参考以下文章

React Router v4 - 切换组件时保持滚动位置

返回 ListView 时保持/保存/恢复滚动位置

UICollectionView 保持水平列表滚动位置

带有引导警报的Angularjs-向下滚动时将警报保持在屏幕上

如何将其他文本附加到 UIWebView

Flutter - 在列表中添加新项目时保持滚动位置