This solution proposes a method for lazy-rendering only the items currently in view based on the edited version of the original question. The goal is to allow users to scroll through the list freely, similar to the behavior of a text editor. In other words, the scroll should cover the "height" of all items, but only display a few in the DOM at a time.
Before implementing this, make sure to install the angular-inview
plugin.
To calculate the scroll height, you need something to reserve space for your array items. Start by creating an array with 3000 simple items (or integrate with infinite scroll as needed).
var $app = angular.module('app', ['infinite-scroll']);
$app.controller('listingController', function($scope, $window) {
$scope.listOfItems = new Array($window._bootstrappedData.length);
$scope.loadItem = function($index,$inview) {
if($inview) {
$scope.listOfItems[$index] = $window._bootstrappedData[$index];
}
}
});
Considering variable item heights, it's advisable to create a placeholder representing the pre-rendered content.
<div ng-controller="listingController">
<ul>
<li ng-repeat="item in listOfItems track by $index" in-view="loadItem($index,$inview)" style="min-height:100px"><div ng-if="item">{{item.name}}</div></li>
</ul>
</div>
Utilizing ng-if
helps optimize rendering efficiency. When an item comes into view while scrolling, it will be automatically displayed. To introduce a delay before showing the item, consider adding a timeout within the loadItem
function that cancels if the same index goes out of view quickly.
Note: To entirely avoid adding elements to the DOM, set your scrollable area to a multiple of the "placeholder" height. Then develop a directive that uses this height to determine which items should be displayed. As new items appear, include their heights and position them correctly, adjusting the displayed elements accordingly. However, this approach might be too extreme and unnecessary.