際際滷

際際滷Share a Scribd company logo
stickyHeader.js
About Russell Heimlich
            Sole developer at the
             Pew Research Center

            Creator of
             dummyimage.com

            Frontend and
             Backend Developer

            @kingkool68
What Does stickyHeader.js Do?
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
Inspired By Spreadsheets
Obsessable.coms Comparator
Obsessable.coms Comparator




http://www.youtube.com/watchv=SN7aslrx2TE&feature=player_detailpage#t=150s
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)
I Thought I Could Just Use CSS...


thead {
    position:fixed;
}
NOPE!
(but this CSS works better on todays browsers)
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
Code Time!
Wait For The Document To Load
$(document).ready(function () {
    ... the rest of the code goes here ...
}
Find All stickyHeader Tables
var tables = $('table.stickyHeader');
tables.each(function(i){
      ... the rest of the code goes here ...
});
Clone The <thead>
var table = tables[i];


var theadClone = $(table).find('thead').clone(true);


var stickyHeader =
$('<div></div>').addClass('stickyHeader hide');
.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/
Append the Cloned <thead>
stickyHeader.append( $('<table></table') )
  .find('table').append(theadClone);


$(table).after(stickyHeader);
The HTML So Far
<table class=stickyHeader>
   <thead>....</thead>
   ...
</table>


<div class=stickyHeader hide>
 <table>
    <thead>...</thead>
  </table>
</div>
Back to the JavaScript
var tableHeight = $(table).height();
Finding The Width Is Trickier
var tableWidth = $(table).width() +
Number( $(table).css( 'padding-left' ).replace(/px/
ig,"") )
+ Number( $(table).css( 'padding-right' ).replace(/
px/ig,"") )
+ Number( $(table).css( 'border-left-
width' ).replace(/px/ig,"") )
+ Number( $(table).css( 'border-right-
width' ).replace(/px/ig,"") );
Why So Complicated?
 width() doesnt account for padding and
  border widths.


 Should have used outerWidth() instead.
Why Do We Need Table Dimensions?
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.
Now To Determine <th> Height
var headerCells = $(table).find('thead th');


var headerCellHeight =
$(headerCells[0]).height();
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);
}
Does The Browser Support postion:fixed?
var no_fixed_support = false;
if (stickyHeader.css('position') == "absolute") {
    no_fixed_support = true;
}
stickyHeader.css
.hide {
    display:none;
}
div.stickyHeader {
    position:fixed;
    _position:absolute;
    top:0;
}
IE6 Doesnt Support position:fixed
 We can use CSS to determine if were dealing
  with IE6


 IE6 will be positioned using JavaScript instead
The Underscore Hack
 .property: value; - Targets IE7 and below
 _property: value; - Targets IE6 and below


 Think of it like an unofficial browser prefix
Determining The Cutoff Points
var cutoffTop = $(table).offset().top;


var cutoffBottom =
cutoffTop + tableHeight - headerCellHeight;
Show/Hide The stickyHeader On Scroll
$(window).scroll(function() {
      var currentPosition = $(window).scrollTop();
      //More Code Will Go Here!
});
Top of the Table (446px)

   Top of the Viewport (627px)




Bottom of the Table (6000+px)
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');
     }
 }
Otherwise Hide The stickyHeader
else {
    stickyHeader.addClass('hide');
}
Notes About Styling
.stickyHeader Needs A Background Color
 It is an overlay after all...
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 { ... }
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
Thoughts On Different Libraries
 Prototype: Extends JavaScript Language
 jQuery: Makes JavaScript Easier
 MooTools: Hybrid Prototype/jQuery
 Dojo Toolkit: WTF?!?!
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
The Code Is Available
 https://github.com/kingkool68/stickyHeader


 http://svn.kingkool68.com/projects/
  stickyHeader/


 Demos: http://dev.kingkool68.com/
  stickyHeader/

More Related Content

stickyHeader.js

  • 2. About Russell Heimlich Sole developer at the Pew Research Center Creator of dummyimage.com Frontend and Backend Developer @kingkool68
  • 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; }
  • 10. NOPE! (but this CSS works better on todays browsers)
  • 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();
  • 20. Finding The Width Is Trickier var tableWidth = $(table).width() + Number( $(table).css( 'padding-left' ).replace(/px/ ig,"") ) + Number( $(table).css( 'padding-right' ).replace(/ px/ig,"") ) + Number( $(table).css( 'border-left- width' ).replace(/px/ig,"") ) + Number( $(table).css( 'border-right- width' ).replace(/px/ig,"") );
  • 21. Why So Complicated? width() doesnt account for padding and border widths. Should have used outerWidth() instead.
  • 22. Why Do We Need Table Dimensions?
  • 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; }
  • 27. stickyHeader.css .hide { display:none; } div.stickyHeader { position:fixed; _position:absolute; top:0; }
  • 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'); } }
  • 34. Otherwise Hide The stickyHeader else { stickyHeader.addClass('hide'); }
  • 36. .stickyHeader Needs A Background Color It is an overlay after all...
  • 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/