I am trying to implement a 'sticky' scroll on dynamic content. My current working example can be found here. It seems to be working, but I encounter a small 'flicker' when new items are appended. This issue seems to be related to the setTimeout(0) function. However, if the timeout is removed, the example does not work properly when trying to add 50 new items. Unfortunately, using virtual/custom scroll solutions like in the Ionic example is not an option. The scroll must be native HTML.
Any ideas on how to solve this problem?
HTML:
<body ng-app="demoApp">
<div ng-controller="TestCtrl">
<div id="first">
<list item-source="items" id="list"></list>
</div>
<div>
Total: {{items.length}}
<button type="button" ng-click="prepend(1);">Prepend (1)</button>
</div>
</div>
</body>
JavaScript:
(function(angular) {
var app = angular.module('demoApp', []).controller('TestCtrl', function($scope) {
$scope.items = [];
$scope.count = 0;
$scope.manualCount = 0;
$scope.prepend = function(count){
for(var i = 1; i <= count; i++){
$scope.count++;
$scope.items.unshift({
imageSrc: 'http://placehold.it/90x140&text='+$scope.count
});
}
};
}).directive('list', ['$timeout', function($timeout){
return {
restrict: "EA",
transclude: false,
replace: false,
template: '<div id="list_wrapper"><div list-item ng-repeat="item in itemSource track by $index" class="item"><img ng-src="{{item.imageSrc}}"/></div></div>',
scope: {
itemSource: '='
},
compile: function(){
return {
pre: function(scope, element, attrs, ctrl){
ctrl.setElement(element[0]);
}
};
},
controller: function($scope){
var element = '';
$scope.linesCount = 0;
var colcount = 3;
this.setElement = function(el){
element = el;
};
this.addItem = function(item){
var newLinesCount = Math.ceil($scope.itemSource.length / colcount);
var linesInserted = newLinesCount - $scope.linesCount;
if(linesInserted > 0){
var prevScroll = element.scrollTop;
$timeout(function(){
var newScroll = prevScroll + (item.clientHeight * linesInserted);
element.scrollTop = newScroll;
}, 0);
}
$scope.linesCount = newLinesCount;
};
}
};
}]).directive('listItem', [function(){
return {
require: "^list",
link: function(scope, element, attributes, listCtrl){
listCtrl.addItem(element[0]);
}
};
}]);
})(window.angular);