Fix 1-pixel offset rounding problems
parent
0abc99b619
commit
34b4a2c4e5
|
@ -1,7 +1,7 @@
|
|||
// Simple Sticky Header and Column implementation for HTML tables
|
||||
// (c) Vitaliy Filippov 2016
|
||||
// License: MPL 2.0+
|
||||
// Version: 2016-08-12
|
||||
// Version: 2016-08-13
|
||||
|
||||
// USAGE:
|
||||
// makeStickyHeaders(table): add sticky header and footer to table
|
||||
|
@ -27,9 +27,23 @@
|
|||
// WARNING 5: make sure you have no CSS rules that will differ on the original header row/column and cloned one,
|
||||
// and that min/max width/height rules apply to the second row/column, not the first header one.
|
||||
|
||||
(function() {
|
||||
|
||||
var _scri = 0;
|
||||
|
||||
function makeStickyHeaders(table)
|
||||
function getOffsetRect(e)
|
||||
{
|
||||
var b = e.getBoundingClientRect();
|
||||
var r = {
|
||||
left: Math.round(b.left),
|
||||
top: Math.round(b.top),
|
||||
};
|
||||
r.width = Math.round(b.right)-r.left;
|
||||
r.height = Math.round(b.bottom)-r.top;
|
||||
return r;
|
||||
}
|
||||
|
||||
window.makeStickyHeaders = function(table)
|
||||
{
|
||||
if (!table._scrstyle)
|
||||
{
|
||||
|
@ -48,11 +62,13 @@ function makeStickyHeaders(table)
|
|||
sr.children[0].style.display = 'block';
|
||||
sr.children[0].style.position = 'absolute';
|
||||
sr.children[0].style.padding = '0';
|
||||
var pb = getOffsetRect(rs[0]);
|
||||
for (var i = 0; i < rs[0].children.length; i++)
|
||||
{
|
||||
var e = rs[0].children[i];
|
||||
w[i] = e.offsetWidth;
|
||||
l[i] = e.offsetLeft;
|
||||
var b = getOffsetRect(e);
|
||||
w[i] = b.width;
|
||||
l[i] = b.left-pb.left;
|
||||
}
|
||||
table._widths = w;
|
||||
table._sizerow = sr;
|
||||
|
@ -99,7 +115,7 @@ function makeStickyHeaders(table)
|
|||
// 3) remember all heights
|
||||
var hs = [];
|
||||
for (var i = rs.length-1; i >= 1; i--)
|
||||
hs[i] = rs[i].offsetHeight;
|
||||
hs[i] = getOffsetRect(rs[i]).height;
|
||||
// 4) make other changes
|
||||
for (var i = rs.length-1; i >= 1; i--)
|
||||
{
|
||||
|
@ -111,7 +127,7 @@ function makeStickyHeaders(table)
|
|||
e.style.height = hs[i]+'px';
|
||||
e.style.width = w[0]+'px';
|
||||
}
|
||||
var row0top = rs[0].offsetTop;
|
||||
var row0top = getOffsetRect(rs[0]).top;
|
||||
addListener(table.parentNode, 'scroll', function(e)
|
||||
{
|
||||
var l = this.scrollLeft, t = this.scrollTop;
|
||||
|
@ -121,7 +137,7 @@ function makeStickyHeaders(table)
|
|||
}
|
||||
|
||||
// check if row(s) are not yet initialised and fix them
|
||||
function initStickyRows(table, trs, nocols)
|
||||
window.initStickyRows = function(table, trs, nocols)
|
||||
{
|
||||
var ntrs = [];
|
||||
for (var i = 0; i < trs.length; i++)
|
||||
|
@ -132,7 +148,7 @@ function initStickyRows(table, trs, nocols)
|
|||
}
|
||||
|
||||
// handle non-header row(s) change with O(1) reflow count
|
||||
function fixStickyRows(table, trs, nocols)
|
||||
window.fixStickyRows = function(table, trs, nocols)
|
||||
{
|
||||
// (1) make some changes
|
||||
var e, d;
|
||||
|
@ -167,12 +183,13 @@ function fixStickyRows(table, trs, nocols)
|
|||
}
|
||||
// (2) <REFLOW> caused by offsetWidth/offsetHeight
|
||||
// (3) remember sizes
|
||||
var w = [], h = [];
|
||||
var w = [], h = [], b;
|
||||
for (var i = 0; i < trs.length; i++)
|
||||
{
|
||||
e = trs[i].children[1];
|
||||
w[i] = e.offsetWidth;
|
||||
h[i] = e.offsetHeight;
|
||||
b = getOffsetRect(e);
|
||||
w[i] = b.width;
|
||||
h[i] = b.height;
|
||||
}
|
||||
// (4) apply sizes
|
||||
for (var i = 0; i < trs.length; i++)
|
||||
|
@ -185,14 +202,14 @@ function fixStickyRows(table, trs, nocols)
|
|||
fixStickyColumnSizes(table);
|
||||
}
|
||||
|
||||
function fixStickyColumnSizes(table, force)
|
||||
window.fixStickyColumnSizes = function(table, force)
|
||||
{
|
||||
// check&fix column sizes
|
||||
var changed = false, resizeFixed = false;
|
||||
for (var i = 1; i < table._sizerow.children.length; i++)
|
||||
{
|
||||
var ne = table._sizerow.children[i];
|
||||
var nw = ne.offsetWidth;
|
||||
var nw = getOffsetRect(ne).width;
|
||||
var cw = table._widths[i-1];
|
||||
if (nw != cw || force)
|
||||
{
|
||||
|
@ -205,13 +222,13 @@ function fixStickyColumnSizes(table, force)
|
|||
if (changed)
|
||||
{
|
||||
// reposition fixed header
|
||||
var w = [], h = [], l = [], b;
|
||||
var w = [], h = [], l = [], b, pb = getOffsetRect(table._sizerow);
|
||||
for (var i = 0; i < table._sizerow.children.length; i++)
|
||||
{
|
||||
b = table._sizerow.children[i];
|
||||
w[i] = b.offsetWidth;
|
||||
h[i] = b.offsetHeight;
|
||||
l[i] = b.offsetLeft;
|
||||
b = getOffsetRect(table._sizerow.children[i]);
|
||||
w[i] = b.width;
|
||||
h[i] = b.height;
|
||||
l[i] = b.left-pb.left;
|
||||
}
|
||||
b = table.rows[0].children[0];
|
||||
b.style.width = w[1]+'px';
|
||||
|
@ -228,7 +245,7 @@ function fixStickyColumnSizes(table, force)
|
|||
// resize fixed column
|
||||
var h = [];
|
||||
for (var i = 0; i < table.rows.length; i++)
|
||||
h[i] = table.rows[i].children[1].offsetHeight;
|
||||
h[i] = getOffsetRect(table.rows[i].children[1]).height;
|
||||
for (var i = 0; i < table.rows.length; i++)
|
||||
{
|
||||
if (i != 1)
|
||||
|
@ -242,7 +259,7 @@ function fixStickyColumnSizes(table, force)
|
|||
}
|
||||
|
||||
// handle header row change
|
||||
function fixStickyHeader(table, nocols)
|
||||
window.fixStickyHeader = function(table, nocols)
|
||||
{
|
||||
var tr = table.rows[0];
|
||||
var sr = table._sizerow;
|
||||
|
@ -293,3 +310,5 @@ function fixStickyHeader(table, nocols)
|
|||
if (!nocols)
|
||||
fixStickyColumnSizes(table);
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
Loading…
Reference in New Issue