Maintain scroll position when adding content to list (AngularJS)

I am trying to add some elements to a list in a scrollable container using ng-repeat , and the recent one at the top of the list. I should also maintain the scroll position if the scrollbar of the container is not at the very top when adding content.

Here is my solution, but I still have a problem. There is always a flicker after angular selects the added elements in 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> 
+5
source share
1 answer

I found this post and changed $timeout to $scope.$$postDigest . Now it works as expected.

 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> 
+6
source

All Articles