I have a table and I'd like to freeze the header row along with a specific number of columns. While I managed to achieve this, it's quite slow on larger tables. Is there a more efficient approach to get the same outcome? I experimented with using $(this).position().left+'px'
instead of freezePos
, but it only worsened the performance (is there a tool available for comparing speeds?).
The process of calculating positions seems cumbersome. Ideally, I would prefer to lock cells along the x axis without explicitly setting a left
property. Additionally, fixing widths on these cells isn't optimal. Are there any other methods I can implement to optimize this?
Is there no CSS equivalent to 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>
(Content rows truncated for brevity)
</tbody>
</table>
</div>