stickyHeader.js is a script I wrote to make table headers stick to the top of the viewport of a browser when scrolling down them. This makes it easier to understand the data. This presentation walks you through how I built it.
The code is available at https://github.com/kingkool68/stickyHeader
4. What Does stickyHeader.js Do?
Table headers stick to the top of the viewport
when you scroll down data tables
Long data tables become easier to read
Has nothing to do with the Sticky Footer
CSS technique
8. stickyHeader.js
Written by me sometime in 2008 while at
USNews.com
Just include the script and 2 CSS rules
Works on any table with class=stickyHeader
46 lines (uncompressed)
9. I Thought I Could Just Use CSS...
thead {
position:fixed;
}
11. Plan B
Create a DIV after the table
Clone the table header and insert it into the DIV
Position the DIV using CSS
Show/hide the DIV as needed using JavaScript
13. Wait For The Document To Load
$(document).ready(function () {
... the rest of the code goes here ...
}
14. Find All stickyHeader Tables
var tables = $('table.stickyHeader');
tables.each(function(i){
... the rest of the code goes here ...
});
15. Clone The <thead>
var table = tables[i];
var theadClone = $(table).find('thead').clone(true);
var stickyHeader =
$('<div></div>').addClass('stickyHeader hide');
16. .clone( [withDataAndEvents] )
A Boolean indicating whether event handlers
should be copied along with the elements.
As of jQuery 1.4, element data will be copied as
well.
http://api.jquery.com/clone/
17. Append the Cloned <thead>
stickyHeader.append( $('<table></table') )
.find('table').append(theadClone);
$(table).after(stickyHeader);
18. The HTML So Far
<table class=stickyHeader>
<thead>....</thead>
...
</table>
<div class=stickyHeader hide>
<table>
<thead>...</thead>
</table>
</div>
19. Back to the JavaScript
var tableHeight = $(table).height();
23. Table Cell Shiftiness
Table cell widths adjust based on the contents
When we take the <thead> away from the
<table> widths can change, and the illusion of
the stickyHeader effect will be broken.
We need to loop through the cells and set the
width manually to fix this.
24. Now To Determine <th> Height
var headerCells = $(table).find('thead th');
var headerCellHeight =
$(headerCells[0]).height();
25. Match Header Cell Widths
for (i=0; i<headerCells.length; i++) {
var headerCell = $(headerCells[i]);
var cellWidth = headerCell.width();
cellWidth = cellWidth + "px";
$(stickyHeaderCells[i]).css('width', cellWidth);
}
26. Does The Browser Support postion:fixed?
var no_fixed_support = false;
if (stickyHeader.css('position') == "absolute") {
no_fixed_support = true;
}
28. IE6 Doesnt Support position:fixed
We can use CSS to determine if were dealing
with IE6
IE6 will be positioned using JavaScript instead
29. The Underscore Hack
.property: value; - Targets IE7 and below
_property: value; - Targets IE6 and below
Think of it like an unofficial browser prefix
30. Determining The Cutoff Points
var cutoffTop = $(table).offset().top;
var cutoffBottom =
cutoffTop + tableHeight - headerCellHeight;
31. Show/Hide The stickyHeader On Scroll
$(window).scroll(function() {
var currentPosition = $(window).scrollTop();
//More Code Will Go Here!
});
32. Top of the Table (446px)
Top of the Viewport (627px)
Bottom of the Table (6000+px)
33. If The Viewport Is Within The Cutoff Points
if (currentPosition > cutoffTop &&
currentPosition < cutoffBottom) {
stickyHeader.removeClass('hide');
if (no_fixed_support) {
stickyHeader.css('top', currentPosition +
'px');
}
}
37. If You Need To Get Specific
/*Global table header styles */
th { ... }
/*Original stickyHeader table header styles */
table.stickyHeader th { ... }
/*Cloned stickyHeader table header styles */
div.stickyHeader th { ... }
38. Other Versions
Ported over to the 4 most popular libraries
Prototype 1.6.0.3
jQuery 1.3.2
MooTools 1.2.2
Dojo Toolkit 1.3.1
39. Thoughts On Different Libraries
Prototype: Extends JavaScript Language
jQuery: Makes JavaScript Easier
MooTools: Hybrid Prototype/jQuery
Dojo Toolkit: WTF?!?!
40. Other Things I Learned
jQuery handles dimensions the best, other
libraries made me have to write my own.
For logging event data, use document.title
instead of console.log
41. The Code Is Available
https://github.com/kingkool68/stickyHeader
http://svn.kingkool68.com/projects/
stickyHeader/
Demos: http://dev.kingkool68.com/
stickyHeader/