var VirtualScrollMixin = { getInitialState: function () { return { start: 0, stop: 0 }; }, componentWillMount: function(){ if(!this.props.rowHeight){ console.warn("VirtualScrollMixin: No rowHeight specified", this); } }, getPlaceholderTop: function () { var Tag = this.props.placeholderTagName || "tr"; var style = { height: this.state.start * this.props.rowHeight }; var spacer = ; if (this.state.start % 2 === 1) { // fix even/odd rows return [spacer, ]; } else { return spacer; } }, getPlaceholderBottom: function (total) { var Tag = this.props.placeholderTagName || "tr"; var style = { height: Math.max(0, total - this.state.stop) * this.props.rowHeight }; return ; }, componentDidMount: function () { this.onScroll(); }, onScroll: function () { var viewport = this.getDOMNode(); var top = viewport.scrollTop; var height = viewport.offsetHeight; var start = Math.floor(top / this.props.rowHeight); var stop = start + Math.ceil(height / (this.props.rowHeightMin || this.props.rowHeight)); this.setState({ start: start, stop: stop }); }, renderRows: function(elems){ var rows = []; var max = Math.min(elems.length, this.state.stop); for (var i = this.state.start; i < max; i++) { var elem = elems[i]; rows.push(this.renderRow(elem)); } return rows; }, scrollRowIntoView: function(index, head_height){ var row_top = (index * this.props.rowHeight) + head_height; var row_bottom = row_top + this.props.rowHeight; var viewport = this.getDOMNode(); var viewport_top = viewport.scrollTop; var viewport_bottom = viewport_top + viewport.offsetHeight; // Account for pinned thead if (row_top - head_height < viewport_top) { viewport.scrollTop = row_top - head_height; } else if (row_bottom > viewport_bottom) { viewport.scrollTop = row_bottom - viewport.offsetHeight; } }, };