Fix headerHeight logic, implement scrollToNode usable with virtual-scroll

master
Vitaliy Filippov 2017-07-12 23:07:36 +03:00
parent b5060d0296
commit bfc9f24251
1 changed files with 54 additions and 11 deletions

View File

@ -284,13 +284,40 @@ function findSubNodes(node, start, count, result)
return [ skipped, added ];
}
TreeGrid.prototype._findNodes = function(node, start, count)
TreeGrid.prototype._findNodes = function(start, count)
{
var result = [];
findSubNodes(node, start, count, result);
findSubNodes(this.root, start, count, result);
return result;
}
function findNodeIndex(node, target)
{
var index = 0, result;
for (var i = 0; i < node.children.length; i++)
{
if (node.children[i] == target)
return [ index, true ];
index++;
if (!node.children[i].collapsed)
{
result = findNodeIndex(node.children[i], target);
index += result[0];
if (result[1])
return [ index, true ];
}
}
return [ index, false ];
}
TreeGrid.prototype._findNodeIndex = function(node)
{
var result = findNodeIndex(this.root, node);
if (!result[1])
return -1;
return result[0];
}
TreeGrid.prototype._renderNodes = function(nodes)
{
for (var i = 0; i < nodes.length; i++)
@ -512,7 +539,7 @@ TreeGrid.prototype.syncView = function()
if (!this.table.offsetParent)
return;
var headerHeight = (this.stickyRow ? this.thead.getBoundingClientRect().height : 0);
var offsetHeight = this.tableWrapper.clientHeight - headerHeight;
var offsetHeight = this.tableWrapper.clientHeight;
var scrollTop = this.tableWrapper.scrollTop;
var visibleItems = Math.ceil(offsetHeight/this.minItemHeight);
var endStart = this.nodeCount - visibleItems;
@ -520,25 +547,26 @@ TreeGrid.prototype.syncView = function()
if (endStart < 0)
endStart = 0;
// Always render last items
var lastNodes = this._findNodes(this.root, endStart, this.nodeCount-endStart);
var lastNodes = this._findNodes(endStart, this.nodeCount-endStart);
this._setPlaceholder('top', 0);
this._beginSync();
this._renderNodes(lastNodes);
this._syncEnd(lastNodes);
this.lastFirstNodeIndex = 0;
if (endStart > 0)
{
// Calculate virtual scroll
var lastFirst = endStart+this._findVisibleNodeOffset(lastNodes, offsetHeight);
this.lastFirstNodeIndex = endStart+this._findVisibleNodeOffset(lastNodes, offsetHeight-headerHeight);
var avgItemHeight = this.endItemHeight / lastNodes.length;
avgItemHeight = (avgItemHeight < this.minItemHeight ? this.minItemHeight : avgItemHeight);
targetHeight = headerHeight + this.nodeCount*avgItemHeight;
targetHeight = this.nodeCount*avgItemHeight + headerHeight;
if (this.stickyColumn)
this.fixedColSizer.style.height = targetHeight+'px';
this.tableSizer.style.height = targetHeight+'px';
var scrollPos = targetHeight > offsetHeight ? scrollTop / (targetHeight - offsetHeight) : 0;
if (scrollPos > 1)
scrollPos = 1;
var firstVisible = scrollPos*lastFirst;
var firstVisible = scrollPos*this.lastFirstNodeIndex;
var rangeStart = Math.floor(firstVisible);
var rangeCount = visibleItems;
this._addPlaceholder('top', 0);
@ -560,13 +588,13 @@ TreeGrid.prototype.syncView = function()
{
rangeCount = endStart-rangeStart;
}
var visibleNodes = this._findNodes(this.root, rangeStart, rangeCount);
var visibleNodes = this._findNodes(rangeStart, rangeCount);
this._renderNodes(visibleNodes);
this._syncStart(visibleNodes);
this._addPlaceholder('mid', 0);
firstItemHeight = getNodeHeight(visibleNodes[0])*(firstVisible-rangeStart);
}
this._setPlaceholder('top', scrollTop-firstItemHeight-headerHeight);
this._setPlaceholder('top', scrollTop - firstItemHeight);
}
else if (this.stickyColumn)
{
@ -585,14 +613,29 @@ TreeGrid.prototype.syncView = function()
this.syncStickyRow();
if (endStart > 0 && endStart > rangeStart+rangeCount)
for (var i = 0; i < this.tbody.rows.length; i++)
total += (this.tbody.rows[i].getBoundingClientRect().height||0);
if (!this.tbody.rows[i].is_placeholder)
total += (this.tbody.rows[i].getBoundingClientRect().height||0);
}
if (endStart > 0 && endStart > rangeStart+rangeCount)
{
this._setPlaceholder('mid', targetHeight - total - (scrollTop-firstItemHeight));
this._setPlaceholder('mid', targetHeight - headerHeight - total - (scrollTop-firstItemHeight));
}
}
TreeGrid.prototype.scrollToNode = function(node)
{
// With virtual scrolling, we must reverse-engineer positioning to find the node
var nodeIndex = this._findNodeIndex(node);
if (nodeIndex < 0)
return false;
if (this.lastFirstNodeIndex > 0)
{
var offsetHeight = this.tableWrapper.clientHeight;
this.tableWrapper.scrollTop = nodeIndex/this.lastFirstNodeIndex * (this.tableWrapper.scrollHeight - offsetHeight);
}
return true;
}
TreeGrid.prototype.nodeOnHover = function(hover, ev)
{
ev = ev||window.event;