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...