diff options
author | Dries Buytaert <dries@buytaert.net> | 2007-02-06 08:35:13 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2007-02-06 08:35:13 +0000 |
commit | f996fd9568dd2dd09c01740885fea85f77a9ce8b (patch) | |
tree | 762695a08284d407c98914fb12308d863875ddd2 /misc | |
parent | 018bd034c8787ff981cf54c4733b81e364cb92f0 (diff) | |
download | brdo-f996fd9568dd2dd09c01740885fea85f77a9ce8b.tar.gz brdo-f996fd9568dd2dd09c01740885fea85f77a9ce8b.tar.bz2 |
- Patch #112605 by Steven: sticky table headers.
Diffstat (limited to 'misc')
-rw-r--r-- | misc/tableheader.js | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/misc/tableheader.js b/misc/tableheader.js new file mode 100644 index 000000000..97b57ec60 --- /dev/null +++ b/misc/tableheader.js @@ -0,0 +1,109 @@ +// $Id$ + +// Global Killswitch +if (Drupal.jsEnabled) { + // Keep track of all header cells. + var cells = []; + + // Attach to all headers. + $(document).ready(function() { + var z = 0; + $('table thead').each(function () { + // Find table height. + var table = $(this).parent('table')[0]; + var height = $(table).addClass('sticky-table').height(); + var i = 0; + + // Find all header cells. + $('th', this).each(function () { + + // Ensure each cell has an element in it. + var html = $(this).html(); + if (html == ' ') { + html = ' '; + } + if ($(this).children().size() == 0) { + html = '<span>'+ html +'</span>'; + } + + // Clone and wrap cell contents in sticky wrapper that overlaps the cell's padding. + $('<div class="sticky-header" style="position: fixed; visibility: hidden; top: 0px;">'+ html +'</div>').prependTo(this); + var div = $('div.sticky-header', this).css({ + 'marginLeft': '-'+ $(this).css('paddingLeft'), + 'marginRight': '-'+ $(this).css('paddingRight'), + 'paddingLeft': $(this).css('paddingLeft'), + 'paddingTop': $(this).css('paddingTop'), + 'paddingBottom': $(this).css('paddingBottom'), + 'z-index': ++z + })[0]; + cells.push(div); + + // Adjust width to fit cell/table. + var ref = this; + if (!i++) { + // The first cell is as wide as the table to prevent gaps. + ref = table; + div.wide = true; + } + $(div).css('width', parseInt($(ref).width()) + - parseInt($(div).css('paddingLeft')) +'px'); + + // Get position and store. + div.cell = this; + div.table = table; + div.stickyMax = height; + div.stickyPosition = Drupal.absolutePosition(this).y; + }); + }); + }); + + // Track scrolling. + var scroll = function() { + $(cells).each(function () { + // Fetch scrolling position. + var scroll = document.documentElement.scrollTop || document.body.scrollTop; + var offset = scroll - this.stickyPosition - 4; + if (offset > 0 && offset < this.stickyMax - 100) { + $(this).css('visibility', 'visible'); + } + else { + $(this).css('visibility', 'hidden'); + } + }); + }; + $(window).scroll(scroll); + $(document.documentElement).scroll(scroll); + + // Track resizing. + var time = null; + var resize = function () { + // Ensure minimum time between adjustments. + if (time) { + clearTimeout(time); + time = null; + } + time = setTimeout(function () { + + // Precalculate table heights + $('table.sticky-table').each(function () { + this.height = $(this).height(); + }) + + $(cells).each(function () { + // Get position. + this.stickyPosition = Drupal.absolutePosition(this.cell).y; + this.stickyMax = this.table.height; + + // Reflow the cell. + var ref = this.cell; + if (this.wide) { + // Resize the first cell to fit the table. + ref = this.table; + } + $(this).css('width', parseInt($(ref).width()) + - parseInt($(this).css('paddingLeft')) +'px'); + }); + }, 250); + }; + $(window).resize(resize); +} |