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