/table_floating_header.js

http://js-floating-table-headers.googlecode.com/ · JavaScript · 142 lines · 129 code · 12 blank · 1 comment · 30 complexity · 17263a2024b1de8967f0931fc7c65406 MD5 · raw file

  1. var floating_header = function() {
  2. this.header = document.createElement('table');
  3. this.header_height = 0;
  4. this.getkeys = function(obj) {
  5. var keys = new Array();
  6. for ( var key in obj ) {
  7. keys.push(key);
  8. }
  9. return keys;
  10. };
  11. this.getXY = function( o ) {
  12. var y = 0;
  13. var x = 0;
  14. while( o != null ) {
  15. y += o.offsetTop;
  16. x += o.offsetLeft;
  17. o = o.offsetParent;
  18. }
  19. return { "x": x, "y": y };
  20. }
  21. this.setheader = function() {
  22. var win = window.pageYOffset ? window.pageYOffset : 0;
  23. var cel = document.documentElement ? document.documentElement.scrollTop : 0;
  24. var body = document.body ? document.body.scrollTop : 0;
  25. var result = win ? win : 0;
  26. if ( cel && ( ! result || ( result > cel ))) result = cel;
  27. var screenpos = body && ( ! result || ( result > body ) ) ? body : result;
  28. var theady_max = this.getXY(this.table_obj.getElementsByTagName('THEAD')[0]).y + this.table_obj.offsetHeight - this.header_height;
  29. if ( screenpos > this.theady && screenpos < theady_max ) {
  30. this.header.style.top=Math.round(screenpos);
  31. this.header.style.display = 'block';
  32. this.header_height = header.offsetHeight;
  33. }
  34. else {
  35. this.header.style.display = 'none';
  36. }
  37. }
  38. this.addclass = function(obj, newclass) {
  39. if ( obj.classes == null ) {
  40. obj.classes = new Array();
  41. }
  42. obj.classes[newclass] = 1;
  43. obj.className = this.getkeys(obj.classes).join(' ');
  44. return true;
  45. };
  46. this.theady = 0;
  47. this.build_header = function() {
  48. this.table_obj = document.getElementsByTagName('THEAD');
  49. if ( ! this.table_obj ) {
  50. alert("you MUST have <thead> and </thead> tags wrapping the part of the table you want to keep on the screen");
  51. return;
  52. }
  53. this.table_obj = this.table_obj[0];
  54. while ( this.table_obj.tagName != 'TABLE' ) {
  55. if ( this.table_obj.tagName == 'BODY' ) {
  56. alert('The THEAD section MUST be inside a table - how did you do that???');
  57. return;
  58. }
  59. this.table_obj = this.table_obj.parentNode;
  60. }
  61. thead = this.table_obj.getElementsByTagName('THEAD')[0].cloneNode(1);
  62. thead.id = 'copyrow';
  63. this.header.style.position='absolute';
  64. this.header.style.display='none';
  65. this.header.appendChild(thead);
  66. this.header.style.width = this.table_obj.offsetWidth;
  67. var srcths = this.table_obj.getElementsByTagName('THEAD')[0].getElementsByTagName('*');
  68. var copyths = thead.getElementsByTagName('*');
  69. for ( var x = 0; x < copyths.length; x++ ) {
  70. copyths[x].className = srcths[x].className;
  71. copyths[x].align = srcths[x].align;
  72. copyths[x].background = srcths[x].background;
  73. copyths[x].bgColor = srcths[x].bgColor;
  74. copyths[x].colSpan = srcths[x].colSpan;
  75. copyths[x].height = srcths[x].height;
  76. copyths[x].rowSpan = srcths[x].rowSpan;
  77. pr = Math.round(srcths[x].style.paddingRight.split('px')[0]);
  78. pl = Math.round(srcths[x].style.paddingLeft.split('px')[0]);
  79. bl = ( Math.round(srcths[x].style.borderLeftWidth.split('px')[0]) ) ? Math.round(srcths[x].style.borderLeftWidth.split('px')[0]) : 0;
  80. br = ( Math.round(srcths[x].style.borderRightWidth.split('px')[0]) ) ? Math.round(srcths[x].style.borderRightWidth.split('px')[0]) : 0;
  81. pt = Math.round(srcths[x].style.paddingTop.split('px')[0]);
  82. pb = Math.round(srcths[x].style.paddingBottom.split('px')[0]);
  83. bt = Math.round(srcths[x].style.borderTopWidth.split('px')[0]);
  84. bb = Math.round(srcths[x].style.borderBottomWidth.split('px')[0]);
  85. if ( srcths[x].currentStyle ) {
  86. for ( var y in srcths[x].currentStyle ) {
  87. if ( y == 'font' || y == 'top' ) continue;
  88. copyths[x].style[y] = srcths[x].currentStyle[y];
  89. }
  90. pr = Math.round(srcths[x].currentStyle.paddingRight.split('px')[0]);
  91. pl = Math.round(srcths[x].currentStyle.paddingLeft.split('px')[0]);
  92. bl = ( Math.round(srcths[x].currentStyle.borderLeftWidth.split('px')[0]) ) ? Math.round(srcths[x].currentStyle.borderLeftWidth.split('px')[0]) : 0;
  93. pt = Math.round(srcths[x].currentStyle.paddingTop.split('px')[0]);
  94. pb = Math.round(srcths[x].currentStyle.paddingBottom.split('px')[0]);
  95. bt = Math.round(srcths[x].currentStyle.borderTopWidth.split('px')[0]);
  96. }
  97. if ( srcths[x].onclick ) copyths[x].onclick = srcths[x].onclick;
  98. var width = ( srcths[x].offsetWidth - pr - pl > 0 ) ? srcths[x].offsetWidth - pr - pl : 0;
  99. copyths[x].style.position = srcths[x].style.position;
  100. copyths[x].style.top = ( srcths[x].offsetTop - pt - pb > 0 ) ? srcths[x].offsetTop - pt - pb : srcths[x].offsetTop;
  101. copyths[x].style.top = srcths[x].style.top;
  102. copyths[x].style.height = srcths[x].offsetHeight;
  103. copyths[x].style.left = srcths[x].offsetLeft;
  104. if ( ! copyths[x].currentStyle ) {
  105. //copyths[x].style.width = Math.floor(document.defaultView.getComputedStyle(srcths[x],"").getPropertyValue("width").split('px')[0]);
  106. copyths[x].style.width = document.defaultView.getComputedStyle(srcths[x],"").getPropertyValue("width");
  107. }
  108. else {
  109. copyths[x].style.width = srcths[x].offsetWidth - pr - pl; // - bl;
  110. copyths[x].width = srcths[x].width;
  111. }
  112. if ( x == copyths.length - 1 ) {
  113. this.header.style.paddingBottom = pb;
  114. this.header.style.borderBottom = bb;
  115. }
  116. }
  117. this.addclass(this.header, 'main');
  118. document.body.appendChild(this.header);
  119. theady = this.getXY(this.table_obj.getElementsByTagName('THEAD')[0]).y;
  120. }
  121. var origonload = window.onload;
  122. window.onload = function() {
  123. if (origonload) {
  124. origonload();
  125. }
  126. this.build_header();
  127. };
  128. window.onscroll=this.setheader;
  129. };
  130. floating_header();