Fix 1-pixel offset rounding problems

rel-1.0
Vitaliy Filippov 2016-08-13 23:22:13 +03:00
parent 0abc99b619
commit 34b4a2c4e5
1 changed files with 39 additions and 20 deletions

View File

@ -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);
}
})();