JSFiddle - React, Tailwind, and code Playground

by Daedalus

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<div id="app">
  {{logs.length}} Log{{(logs.length > 1 || logs.length === 0 || !logs) ? 's' : ''}}
  <span v-show="logEnd !== 0">
    <span> | Showing: {{logStart}} - {{logEnd}}</span>
  </span>
  <comp :items="logs" :view-height="350" :child-height="50" @change="updateShowing($event)"></comp>
</div>

SCSS

.table-responsive {
  width: 100.1%;
  &.container_table {
    overflow: hidden;
  }
  > .table-bordered {
    border: 0;
    border-collapse: collapse;
    box-sizing: content-box;
    width: 100.1%;
    max-width: 100.1%;
  }
}
.table_outer {
  padding: 0;
  width: 100.1%;
  > thead > tr > th {
    position: relative;
  }
  > tbody > tr > td {
    padding: 0;
    border: none;
  }
  .td_scroll {
    overflow: hidden;
    overflow-y: overlay;
    position: relative;
    display: block;
  }
  .td_content {
    overflow: hidden;
  }
  .table_inner {
    margin-bottom: 0px;
  }
}
.host {
  overflow: hidden;
  overflow-y: auto;
  position: relative;
}
.scrollable-content {
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  position: absolute;
}
.total-padding {
  width: 1px;
  opacity: 0;
}
.table-bordered thead td, .table-bordered thead th { border: 0; }

JavaScript

var comp = {
  template: `
  <div class="table-responsive container_table" :style="{height: viewHeight + 'px'}">
    <table class="table table-bordered table_outer host" ref="table">
      <thead>
        <tr>
          <th>Filename</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td :colspan="1" ref="content">
            <div class="td_scroll" :style="td_scrollHeight" @scroll="refresh()" ref="td_scroll">
              <div class="total-padding" :style="{height:scrollHeight + 'px'}"></div>
              <div class="scrollable-content" :style="{transform:'translateY('+topPadding+'px)'}">
                <div class="table-responsive td_content" :style="{height: (viewHeight - 50) + 'px'}" ref="td_content">
                  <table class="table table-bordered table_inner" ref="table">
                    <thead style="display: none;">
                      <tr>
                        <th>Filename</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="(row, tr_i) in rows" :key="tr_i">
                        <td class="ellipsis" :style="{height: childHeight + 'px'}">
                          <span>{{row['value']}}</span>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>`,
  props: ["items", "viewHeight", "childHeight"],
  data() {
    return {
      scrollHeight: 0,
      topPadding: 0,
      rows: []
    };
  },
  methods: {
    // Below is the problem code
    calculateItems() {
      let start = (
        this.$refs.td_scroll.scrollTop /
        this.$refs.td_scroll.scrollHeight *
        this.items.length
      );
      let viewHeight = this.$refs.td_scroll.getBoundingClientRect().height + 2;
      let end = start + (this.viewHeight / this.childHeight) - 1;

      this.scrollHeight...