PageSourceSearch

https://www.racingtheplanet.com/js/new-fixedTable.js

js racingtheplanet.com collected 2026-10-02 06:56:30 UTC 4,898 bytes, 135 lines download raw bytes

1function fixTable(container) {
2    // Store references to table elements
3    var thead = container.querySelector('thead');
4    var tbody = container.querySelector('tbody');
5
6    // Style container
7    container.style.overflow = 'auto';
8    container.style.position = 'relative';
9
10    // Add inline styles to fix the header row and leftmost column
11    function relayout() {
12        var ths = [].slice.call(thead.querySelectorAll('th'));
13        var tbodyTrs = [].slice.call(tbody.querySelectorAll('tr'));
14
15        /**
16         * Remove inline styles so we resort to the default table layout algorithm
17         * For thead, th, and td elements, don't remove the 'transform' styles applied
18         * by the scroll event listener
19         */
20        tbody.setAttribute('style', '');
21        thead.style.width = '';
22        thead.style.position = '';
23        thead.style.top = '';
24        thead.style.left = '';
25        thead.style.zIndex = '';
26        ths.forEach(function(th) {
27            th.style.display = '';
28            th.style.width = '';
29            th.style.position = '';
30            th.style.top = '';
31            th.style.left = '';
32        });
33        tbodyTrs.forEach(function(tr) {
34            tr.setAttribute('style', '');
35        });
36        [].slice.call(tbody.querySelectorAll('td'))
37            .forEach(function(td) {
38                td.style.width = '';
39                td.style.position = '';
40                td.style.left = '';
41            });
42
43        /**
44         * Store width and height of each th
45         * getBoundingClientRect()'s dimensions include paddings and borders
46         */
47        var thStyles = ths.map(function(th) {
48            var rect = th.getBoundingClientRect();
49            var style = document.defaultView.getComputedStyle(th, '');
50            return {
51                boundingWidth: rect.width,
52                boundingHeight: rect.height,
53                width: parseInt(style.width, 10),
54                paddingLeft: parseInt(style.paddingLeft + 1, 10)
55            };
56        });
57
58        // Set widths of thead and tbody
59        var totalWidth = thStyles.reduce(function(sum, cur) {
60            return sum + cur.boundingWidth;
61        }, 0);
62        tbody.style.display = 'block';
63        tbody.style.width = totalWidth + 'px';
64        thead.style.width = totalWidth - thStyles[0].boundingWidth + 'px';
65
66        // Position thead
67        thead.style.position = 'absolute';
68        thead.style.top = '0';
69        thead.style.left = thStyles[0].boundingWidth + 'px';
70        thead.style.zIndex = 10;
71
72        // Set widths of the th elements in thead. For the fixed th, set its position
73        ths.forEach(function(th, i) {
74            th.style.width = thStyles[i].width + 'px';
75            if (i === 0) {
76                th.style.position = 'absolute';
77                th.style.top = '0';
78                th.style.left = -thStyles[0].boundingWidth + 'px';
79            }
80        });
81
82        // Set margin-top for tbody - the fixed header is displayed in this margin
83        tbody.style.marginTop = thStyles[0].boundingHeight + 'px';
84
85        // Set widths of the td elements in tbody. For the fixed td, set its position
86        tbodyTrs.forEach(function(tr, i) {
87            tr.style.display = 'block';
88            tr.style.paddingLeft = thStyles[0].boundingWidth + 'px';
89            [].slice.call(tr.querySelectorAll('td'))
90                .forEach(function(td, j) {
91                    td.style.width = thStyles[j].width + 'px';
92                    if (j === 0) {
93                        td.style.position = 'absolute';
94                        td.style.left = '0';
95                    }
96                });
97        });
98    }
99
100    // Initialize table styles
101    relayout();
102
103    // Update table cell dimensions on resize
104    window.addEventListener('resize', resizeThrottler, false);
105    var resizeTimeout;
106
107    function resizeThrottler() {
108        if (!resizeTimeout) {
109            resizeTimeout = setTimeout(function() {
110                resizeTimeout = null;
111                relayout();
112            }, 500);
113        }
114    }
115
116    // Fix thead and first column on scroll
117    container.addEventListener('scroll', function() {
118        thead.style.transform = 'translate3d(0,' + this.scrollTop + 'px,0)';
119        var hTransform = 'translate3d(' + this.scrollLeft + 'px,0,0)';
120        thead.querySelector('th').style.transform = hTransform;
121        thead.querySelector('th:nth-child(2)').style.transform = hTransform;
122        [].slice.call(tbody.querySelectorAll('tr > td:first-child,tr > td:nth-child(2)'))
123            .forEach(function(td, i) {
124                td.style.transform = hTransform;
125            });
126    });
127
128    /**
129     * Return an object that exposes the relayout function so that we can
130     * update the table when the number of columns or the content inside columns changes
131     */
132    return {
133        relayout: relayout
134    };
135}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.