/ Published in: JavaScript
Some minor changes to xTableHeaderFixed from http://cross-browser.com/x/lib/view.php?s=xTableHeaderFixed
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
// xTableHeaderFixed r10, Copyright 2006-2010 Michael Foster (Cross-Browser.com) // Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL var xIE8Up; // yuck! /*@cc_on @if (@_jscript_version > 5.7) xIE8Up = true; @end @*/ var xGecko = window.navigator.product == 'Gecko'; // yuckier! function xTableHeaderFixed(tclass, tcon, w, yofs) { // Public Methods this.init = function(tclass, tcon, w, yofs) { _dtor(); return _ctor(tclass, tcon, w, yofs); }; this.paint = function() { _event({ type: 'resize' }); }; // Constructor Code var _i = this, con, tbl, win, cbl = 0, cbt = 0, fp = true, yo = 0, fc = 'xthf-fix-tbl', ac = 'xthf-abs-tbl'; // private properties if (tclass) { _ctor(tclass, tcon, w, yofs); } // Private Methods function _ctor(tclass, tcon, w, yofs) { var i, h, t; tbl = xGetElementsByClassName(tclass, document, 'table'); con = xGetElementById(tcon); if (!tbl || !tbl.length || !con) { return false; } if (!(win = w)) { con.scrollTop = 0; } // Create a header table for each table with tclass. for (i = 0; i < tbl.length; ++i) { h = tbl[i].tHead; if (h) { t = document.createElement('table'); // EDIT - setting these styles explicitly - removes the need to have .css file (unless we are printing) t.className = tclass + ' ' + (w ? fc : ac); t.style.top = 0; t.style.position = (w ? "fixed" : "absolute"); if (tbl[i].cellSpacing !== '') { t.cellSpacing = tbl[i].cellSpacing; } t.appendChild(h.cloneNode(true)); t.id = tbl[i].xthfHdrTblId = 'xthf-' + tclass + '-' + i; if (typeof yofs != 'undefined') { yo = yofs; if (yo === 0) { // t.style.top = xPageY(tbl[i]) + 'px'; // r10 } // else { t.style.top = yo + 'px'; } } document.body.appendChild(t); } else { tbl[i] = null; } } // begin DEBUG if (!w && !xIE8Up && !window.opera) { cbl = xGetComputedStyle(con, 'border-left-width', true), cbt = xGetComputedStyle(con, 'border-top-width', true); } // end DEBUG _event({ type: 'resize' }); xAddEventListener(con, 'scroll', _event, false); xAddEventListener(window, 'resize', _event, false); xAddEventListener(window, 'unload', _dtor, false); return true; } function _dtor() { var i, ht; if (con) { xRemoveEventListener(con, 'scroll', _event); xRemoveEventListener(window, 'resize', _event); xRemoveEventListener(window, 'unload', _dtor); // Remove the header tables from the DOM. for (i = 0; i < tbl.length; ++i) { ht = xGetElementById(tbl[i].xthfHdrTblId); if (ht) { document.body.removeChild(ht); } tbl[i] = null; } tbl = null; con = null; } } function _event(e) // handles scroll and resize events { var i, r; e = e || window.event; r = e.type == 'resize'; for (i = 0; i < tbl.length; ++i) { _paint(tbl[i], r); } } function _paint(t, r) { var i, ht, c1, c2, st, ty, thy, w, sep; if (!t) { return; } ht = xGetElementById(t.xthfHdrTblId); // Hide or show the header table. st = xScrollTop(con, win) + (yo || 0); if (win) { ty = xPageY(t); } else { ty = t.offsetTop; } thy = ty + t.rows[0].offsetTop; if (yo !== 0 && (st <= thy || st > ty + t.offsetHeight - ht.offsetHeight)) { ht.style.left = '-2000%'; // hide it //EDIT - previously was "-2000px" my VDUs are getting bigger! Mine is 1920x1200 and when I expanded across 2 screens I would see the "hidden" table. fp = true; // first-paint after being hidden return; } // Position the header table. ht.style.left = (xPageX(t) - xScrollLeft(con, win) + cbl) + 'px'; if (!win) { ht.style.top = (xPageY(con) + cbt) + 'px'; } if (fp || r) { // Resize the header table THs. c1 = xGetElementsByTagName('th', t.tHead); c2 = xGetElementsByTagName('th', ht.tHead); for (i = 0; i < c1.length; ++i) { w = c1[i].offsetWidth; xTableHeaderFixed.xWidth(c2[i], w); } fp = false; //EDIT - Set the width of the header explicitly try { w = t.offsetWidth; xTableHeaderFixed.xWidth(ht, w); } catch (exception) { alert(exception); } } } } // end xTableHeaderFixed // xWidth r8?, Copyright 2001-2010 Michael Foster (Cross-Browser.com) // Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL // This function is currently experimental and used only by xTableHeaderFixed. xTableHeaderFixed.xWidth = function(e, w) { var pl = 0, pr = 0, b = 0, gcs; if (!(e = xGetElementById(e))) return false; if (xNum(w)) { if (w < 0) w = 0; // return false ??? else w = Math.round(w); } else w = -1; if (xDef(e.style, e.offsetWidth, e.clientWidth)) { if (w >= 0) { if (document.compatMode == 'CSS1Compat') { gcs = xGetComputedStyle; pl = gcs(e, 'padding-left', 1); pr = gcs(e, 'padding-right', 1); b = e.offsetWidth - e.clientWidth; if (window.opera && e.tagName.toLowerCase() != 'table') { b = Math.round(b / 2); // possibly only for TDs and THs !!! haven't yet finished testing in Opera !!! } w -= (pl + pr + b); if (isNaN(w) || w < 0) return false; } e.style.width = w + 'px'; } w = e.offsetWidth; } else { return false; } return w; }; /* DEBUG sep = xGetComputedStyle(t, 'border-collapse') == 'separate';///////////////// for (i = 0; i < c1.length; ++i) { /////// testing something for table 3 /////// w = c1[i].offsetWidth; //if ((xGecko || xIE8Up) && c1[i].colSpan > 1) { if (xGecko && (win || sep) && c1[i].colSpan > 1) { --w; // ??????????????? } xTableHeaderFixed.xWidth(c2[i], w); } */