https://jsfiddle.net/hts79y4p/3/ modified

https://jsfiddle.net/hts79y4p/3/ modified

by fastfasterfastest

HTML

<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script src="https://knockoutjs.com/downloads/knockout-3.5.0.debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<div>
  <div>
    <input type="text" data-bind="value: $root.search, valueUpdate: 'afterkeydown'" />
  </div>
  <div>
    <!-- ko virtualForeach: { data: $root.dataFiltered, as: 'item', offsetSelector: '.js-scroll', loadAmount:11 } -->
    <div>
      <!-- ko text: item.name --><!-- /ko -->
    1</div>
    <!-- /ko -->
  2</div>
</div>

JavaScript

(function() {
  ko.bindingHandlers['virtualForeach'] = {
    // v0.2 - 20180220 - ko.isSubscribable check around data.subscribe

    init: function(element, valueAccessor) {
      var value = valueAccessor(),
        data;

      if (ko.isObservable(value)) {
        data = value;
        value = {};
      } else {
        data = value.data;
      }

      value.offsetAmount = value.offsetAmount || 200;
      value.loadAmount = value.loadAmount || 20;
      value.offsetElement = $.trim(value.offsetSelector).length ? $(element).closest(value.offsetSelector) : $(element);
      value.scrollElement = value.scrollElement || value.offsetElement;

      data.virtualForeachDataLoadAmount = ko.observable(ko.utils.unwrapObservable(value.loadAmount));
      //data.virtualForeachData = ko.observableArray([]);
      data.virtualForeachData = ko.pureComputed(function() {
        var data = this;
        return _.take(ko.unwrap(data), ko.unwrap(data.virtualForeachDataLoadAmount));
      }, data);
      value.data = data.virtualForeachData;

      arguments[1] = function() {
        return value;
      };

      value.scrollElement.scroll(function(e) {
        var shouldLoad = value.offsetElement.prop('scrollTop') > (value.offsetElement.prop('scrollHeight') - value.offsetElement.prop('offsetHeight') - ko.utils.unwrapObservable(value.offsetAmount)),
          actualData = ko.utils.unwrapObservable(data);

        if (actualData.length > ko.unwrap(data.virtualForeachData).length && shouldLoad) {
          data.virtualForeachDataLoadAmount(data.virtualForeachDataLoadAmount() + ko.utils.unwrapObservable(value.loadAmount));
        }
      });

      if (ko.unwrap(data.virtualForeachData).length < ko.unwrap(data).length) {
        // Check we have a scroll
        _.defer(function() {
          if (value.offsetElement.prop('scrollHeight') <= value.offsetElement.prop('clientHeight')) {
            data.virtualForeachDataLoadAmount(ko.unwrap(data.virtualForeachDataLoadAmount) +...