Reputation: 307
I have a table with pretty complex structure thead
. So I can't know scales of rows and cells of thead
before table's body will be filled (it contains hundreds of rows information). How should I make thead
sticky to the top of window, when I scroll down?
thead
's structure looks like this:
I can't divide thead
and tbody
by div
or wrap thead
by div
because thead
's structure depends on tbody
content. I can't change the CSS display
property of 'thead' because it kills all structure.
I tried to copy thead
+ tbody
's first row to other table and toggle display:none
by scroll but original thead
different from copied because original's tbody
have other content.
thead structure: http://jsfiddle.net/ba14fyex/
Upvotes: 0
Views: 396
Reputation: 442
I had a website with same problem and solve it this way. It clones the header when scrolling. I'll be glad if it helps.
https://codepen.io/DannaB67/pen/ayvXWe
CSS
body {
background: #fefefe;
}
table {
width: 720px;
border: 1px solid #e4e4e4;
border-radius: 0px 0px 0 0;
}
thead {width:720px;}
table th {
border: 1px solid black;
background-color: LightCyan;
padding: 0 10px 0;
height: 40px;
width: 710px;
text-align: left;
text-transform: capitalize;
}
table td {
padding: 10px;
border-color: #9fdaed;
border-right: none;
border-left: none;
}
$nav-height: 120px;
.navbar-fixed {
position: fixed;
width:720px;
top: -($nav-height); left:0px;
}
JS
(function($) {
"use strict";
var $navbar = $("#navbar"),
y_pos = $navbar.offset().top,
height = $navbar.height();
$(document).scroll(function() {
var scrollTop = $(this).scrollTop();
if (scrollTop > y_pos + height) {
$navbar.addClass("navbar-fixed").animate({
top: 0
});
} else if (scrollTop <= y_pos) {
$navbar.removeClass("navbar-fixed").clearQueue().animate({
top: "-20px"
}, 0);
}
});
});
HTML
<table>
<thead id="navbar">
<tr>
<th colspan="5">1</th>
<th colspan="9">2</th>
</tr>
<tr>
<th rowspan="3">3</th>
<th rowspan="3">4</th>
<th rowspan="3">5</th>
<th rowspan="3">6</th>
<th></th>
<th colspan="3">7</th>
<th colspan="3">8</th>
<th colspan="3">9</th>
</tr>
<tr>
<th>10</th>
<th>11</th>
<th colspan="2">12</th>
<th>13</th>
<th colspan="2">14</th>
<th>16</th>
<th colspan="2">17</th>
</tr>
<tr>
<th>18</th>
<th>19</th>
<th>20</th>
<th>21</th>
<th>22</th>
<th>23</th>
<th>24</th>
<th>25</th>
<th>26</th>
<th>27</th>
</tr>
</thead>
<tbody>
<tr class="table-row">
<td>a</td>
<td>b</td>
<td>c</td>
<td>1881</td>
<td>c</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td style="color:green;">2270</td>
<td style="color:green;">1318</td>
<td style="color:green;">138</td>
</tr>
</tbody>
</table>
Upvotes: 0
Reputation: 307
I've solved it by copying table without body to div
so i've got:
<div id='wrapper'>
<table id='copy'>...</table>
</div>
<table id='origin>...</table>
And using jQuery I copy all width and height properties from origin to copy:
$(function(){
var origin = $("#origin"),
curTablePos = origin.position().top;
$("#origin thead th").each(function(i){
var replic = $($("#copy thead th")[i]),
$this = $(this);
replic.width($this.width());
replic.height($this.height());
});
$("#copy").width(origin.width()); //setting up width
$(window).scroll(function(e){
var wrapper = $("#wrapper");
if(window.scrollY >= curTablePos){
wrapper.show();
}else{
wrapper.hide();
}
})
});
Please comment if you can do it better, because I find this solution pretty hardcore html-porn.
Upvotes: 1