冻结动态表的列而没有一个丑陋的循环和固定的宽度/左值?

时间:2019-01-19 19:49:01

标签: javascript jquery html css sticky

我有一张要冻结标题行和n列列的表。我的工作效果很好,但是在一张大桌子上,速度太慢了。有没有更好的方法来达到相同的结果?我尝试使用$(this).position().left+'px'而不是freezePos,但这似乎使它变得更慢(那里有我可以A / B速度的工具吗?)。

计算位置似乎很丑。我希望我可以将x轴上的单元格锁定而无需设置left。这也迫使我在那些单元格上使用固定宽度,这是不理想的。我还能做些什么来改善这一点?

没有CSS position: fixed-x对吗?

$.fn.freezeColumns = function() {
  var freezePos = 0;
  $('thead th').each(function(index, val) {
    if(index == 2) return false; // Exit after n elements
    var $self = $(this);
    var curWidth = $self.outerWidth();
    $('th:nth-child(' + parseInt(index+1) + '), td:nth-child(' + parseInt(index+1) + ')').addClass('sticky').css('left', freezePos);
    freezePos += curWidth;
  });
};
$(document).freezeColumns();
body {
  font-family: 'Lucida Grande';
}

div {
  width: 500px;
  height: 200px;
  overflow: scroll;
}

td,
th {
  padding: 2px 10px;
  white-space: nowrap;
}

thead th {
  position: sticky;
  position: -webkit-sticky;
  top: 0;
  background: #146775;
  color: white;
  z-index: 3;
}

.sticky {
  position: sticky;
  position: -webkit-sticky;
}
th.sticky {
  z-index: 4;
}
td.sticky {
  background: #569CA8;
  color: white;
  z-index: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <table cellspacing="0">
    <thead>
      <tr>
        <th>Header 1 Title</th>
        <th>Header 2 Title X</th>
        <th>Header 3 Title XX</th>
        <th>Header 4 Title XXX</th>
        <th>Header 5 Title XXXX</th>
        <th>Header 7 Title XXXXX</th>
        <th>Header 8 Title XXXXXX</th>
        <th>Header 9 Title XXXXXXX</th>
        <th>Header 10 Title XXXXXXX</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
      <tr>
        <td>Column 1</td>
        <td>Column 2</td>
        <td>Column 3</td>
        <td>Column 4</td>
        <td>Column 5</td>
        <td>Column 7</td>
        <td>Column 8</td>
        <td>Column 9</td>
        <td>Column 10</td>
      </tr>
    </tbody>
  </table>
</div>

1 个答案:

答案 0 :(得分:0)

我什至都不会冻结元素(如果我正确理解了您要做什么的话)。而是创建一个函数,该函数可克隆N个行以及标头,并将它们绝对定位在原始行上。如有必要,也许可以在原件上放置隐形滤镜。

编辑:

我再次查看了代码。通过将尽可能多的公共属性移到jquery循环之外,可以提高性能。像这样:

$.fn.newFreeze = function(num) {
  var left = 0;
  for (var i = 1; i < num + 1; i++) {
    left += i === 1 ? 0 : $(`th:nth-child(${i - 1})`).outerWidth();
    $(`th:nth-child(${i}),td:nth-child(${i})`).each(function() {
      $(this).css({
        left,
        zIndex: 4,
      })
    })
  }
}
th, td {
  position: sticky;
  position: -webkit-sticky;
}