JSFiddle - React, Tailwind, and code Playground
by Daniel Lamb
HTML
<script src="http://knockoutjs.com/downloads/knockout-2.3.0rc.js"></script>
<script src="https://s3.amazonaws.com/github-raw/infinitescroll.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<body style="width: 100%; height: 100%; font-family: Sans-serif;">
<div>
<label>Total items:</label>
<strong data-bind="text: items().length"></strong>
<br/>
<label>Display items:</label>
<strong data-bind="text: items.infinitescroll.numItemsPerPage()"></strong>
<br/>
<label>Rendered items:</label>
<strong data-bind="text: items.infinitescroll.displayItems().length - items.infinitescroll.firstHiddenIndex()"></strong>
</div>
<div>
<label>Num items per page:</label>
<strong data-bind="text: items.infinitescroll.numItemsPerPage()"></strong>
<br/>
<label>First visible item index:</label>
<strong data-bind="text: items.infinitescroll.firstVisibleIndex()"></strong>
<br/>
<label>Last visible item index:</label>
<strong data-bind="text: items.infinitescroll.lastVisibleIndex()"></strong>
</div>
<div>
<label>container w/h:</label>
<strong data-bind="text: items.infinitescroll.viewportWidth() + 'px / ' + items.infinitescroll.viewportHeight() + 'px'"></strong>
<br/>
<label>each item w/h:</label>
<strong data-bind="text: items.infinitescroll.itemWidth() + 'px / ' + items.infinitescroll.itemHeight() + 'px'"></strong>
</div>
<ul id="itemsUL" data-bind="foreach: items.infinitescroll.displayItems" style="display: block; position:absolute; width: 50%; height:50%; overflow-y: auto; background: #ffeeff;">
<li class="item" style="display:block; position:relative; height: 20px;">
<!-- ko if: $index() >= $root.items.infinitescroll.firstHiddenIndex() -->
<span data-bind="text: ($index() + 1) + '.' + $data"></span>
<!-- /ko -->
</li>
</ul>
</body>
JavaScript
// knockout-js-infinite-scroll (common usage)
ViewModel = function () {
var self = this;
self.items = ko.observableArray();
self.items.extend({
infinitescroll: {}
});
// detect resize
$(window).resize(function() {
updateViewportDimensions();
});
// tell infinte-scroll about the current scroll position
// (debounce is important for ie11 smooth scroll problems! and also generally nicer in all browsers)
$('#itemsUL').scroll(_.debounce(function() {
self.items.infinitescroll.scrollY($('#itemsUL').scrollTop());
// add more items if scroll reaches the last 100 items
if (self.items.peek().length - self.items.infinitescroll.lastVisibleIndex.peek() <= 100) {
populateItems(100);
}
}, 250));
// update dimensions of infinite-scroll viewport and item
function updateViewportDimensions() {
var itemsRef = $('#itemsUL'),
itemRef = $('.item').first(),
itemsWidth = 240,
itemsHeight = 300,
itemWidth = 220,
itemHeight = 20;
self.items.infinitescroll.viewportWidth(itemsWidth);
self.items.infinitescroll.viewportHeight(itemsHeight);
self.items.infinitescroll.itemWidth(itemWidth);
self.items.infinitescroll.itemHeight(itemHeight);
}
updateViewportDimensions();
// init items
function populateItems(numTotal) {
var existingItems = self.items(),
item = '',
alphabet = 'abcdefghijklmnopqrstuvwxyz',
numTotal = numTotal || 500;
for (var i = 0; i < numTotal; i++) {
item = '';
for( var j = 0; j < Math.floor(Math.random() * 20) + 1; j++ ) {
item += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
}
existingItems.push(item);
}
self.items(existingItems);
}
populateItems();
}
ko.applyBindings(new...