virtual Scroll table

tal como en https://github.com/sergi/virtual-list

HTML

<h1>Virtual Scroll table</h1>
<div id="container"></div>

CSS

html, body{
  width:100%;height:100%;
  margin:0px;padding:0px;
}

.fila{
  width:100%;
}
.celda{
  	position:absolute;
  	height:18px;
  	color:black;
  	/*width:100%;*/
    font-family:Arial;
    text-overflow: ellipsis;
    vertical-align: middle;
    border: 1px solid transparent;
    border-right: 1px dotted silver;
    border-bottom-color: silver;
      cursor: default;
    padding-top:2px;
    padding-bottom:2px;
  }
  
  .green_bg{
  	color:black;
  	background:#BADA55;
  }
  
  .noselect {
  -webkit-touch-callout: none; /* iOS Safari */
  -webkit-user-select: none;   /* Chrome/Safari/Opera */
  -khtml-user-select: none;    /* Konqueror */
  -moz-user-select: none;      /* Firefox */
  -ms-user-select: none;       /* Internet Explorer/Edge */
  user-select: none;           /* Non-prefixed version, currently
                                  not supported by any browser */
}

#container{height:300px;}

JavaScript

/**
 * Creates a virtually-rendered scrollable list.
 * @param {object} config
 * @constructor
 */
function VirtualList(config) {
  var width = (config && config.w + 'px') || '100%';
  var height = (config && config.h + 'px') || '100%';
  var itemHeight = this.itemHeight = config.itemHeight;

  this.items = config.items;
  this.columns=config.columns;
  this.generatorFn = config.generatorFn;
  this.totalRows = config.totalRows || (config.items && config.items.length);

  var scroller = VirtualList.createScroller(itemHeight * this.totalRows);
  this.container = VirtualList.createContainer(width, height);
  this.container.appendChild(scroller);

  var screenItemsLen = Math.ceil(config.h / itemHeight);
  // Cache 4 times the number of items that fit in the container viewport
  this.cachedItemsLen = screenItemsLen * 3;
  this._renderChunk(this.container, 0);

  var self = this;
  var lastRepaintY;
  var maxBuffer = screenItemsLen * itemHeight;
  var lastScrolled = 0;

  // As soon as scrolling has stopped, this interval asynchronouslyremoves all
  // the nodes that are not used anymore
  this.rmNodeInterval = setInterval(function() {
    if (Date.now() - lastScrolled > 100) {
      var badNodes = document.querySelectorAll('[data-rm="1"]');
      for (var i = 0, l = badNodes.length; i < l; i++) {
        self.container.removeChild(badNodes[i]);
      }
    }
  }, 300);

  function onScroll(e) {
	  e = e || window.event; //ie
	  var te = e.target || e.srcElement; //ie
    var scrollTop = te.scrollTop; // Triggers reflow
    if (!lastRepaintY || Math.abs(scrollTop - lastRepaintY) > maxBuffer) {
      var first = parseInt(scrollTop / itemHeight) - screenItemsLen;
      self._renderChunk(self.container, first < 0 ? 0 : first);
      lastRepaintY = scrollTop;
    }

    lastScrolled = Date.now();
    e.preventDefault && e.preventDefault();
  }

  if(this.container.attachEvent)
	  this.container.attachEvent('onscroll', onScroll);
  else
	 ...