Fix headerHeight logic, implement scrollToNode usable with virtual-scroll
parent
b5060d0296
commit
bfc9f24251
65
treegrid.js
65
treegrid.js
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue