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 ];
|
return [ skipped, added ];
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeGrid.prototype._findNodes = function(node, start, count)
|
TreeGrid.prototype._findNodes = function(start, count)
|
||||||
{
|
{
|
||||||
var result = [];
|
var result = [];
|
||||||
findSubNodes(node, start, count, result);
|
findSubNodes(this.root, start, count, result);
|
||||||
return 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)
|
TreeGrid.prototype._renderNodes = function(nodes)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < nodes.length; i++)
|
for (var i = 0; i < nodes.length; i++)
|
||||||
|
@ -512,7 +539,7 @@ TreeGrid.prototype.syncView = function()
|
||||||
if (!this.table.offsetParent)
|
if (!this.table.offsetParent)
|
||||||
return;
|
return;
|
||||||
var headerHeight = (this.stickyRow ? this.thead.getBoundingClientRect().height : 0);
|
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 scrollTop = this.tableWrapper.scrollTop;
|
||||||
var visibleItems = Math.ceil(offsetHeight/this.minItemHeight);
|
var visibleItems = Math.ceil(offsetHeight/this.minItemHeight);
|
||||||
var endStart = this.nodeCount - visibleItems;
|
var endStart = this.nodeCount - visibleItems;
|
||||||
|
@ -520,25 +547,26 @@ TreeGrid.prototype.syncView = function()
|
||||||
if (endStart < 0)
|
if (endStart < 0)
|
||||||
endStart = 0;
|
endStart = 0;
|
||||||
// Always render last items
|
// 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._setPlaceholder('top', 0);
|
||||||
this._beginSync();
|
this._beginSync();
|
||||||
this._renderNodes(lastNodes);
|
this._renderNodes(lastNodes);
|
||||||
this._syncEnd(lastNodes);
|
this._syncEnd(lastNodes);
|
||||||
|
this.lastFirstNodeIndex = 0;
|
||||||
if (endStart > 0)
|
if (endStart > 0)
|
||||||
{
|
{
|
||||||
// Calculate virtual scroll
|
// Calculate virtual scroll
|
||||||
var lastFirst = endStart+this._findVisibleNodeOffset(lastNodes, offsetHeight);
|
this.lastFirstNodeIndex = endStart+this._findVisibleNodeOffset(lastNodes, offsetHeight-headerHeight);
|
||||||
var avgItemHeight = this.endItemHeight / lastNodes.length;
|
var avgItemHeight = this.endItemHeight / lastNodes.length;
|
||||||
avgItemHeight = (avgItemHeight < this.minItemHeight ? this.minItemHeight : avgItemHeight);
|
avgItemHeight = (avgItemHeight < this.minItemHeight ? this.minItemHeight : avgItemHeight);
|
||||||
targetHeight = headerHeight + this.nodeCount*avgItemHeight;
|
targetHeight = this.nodeCount*avgItemHeight + headerHeight;
|
||||||
if (this.stickyColumn)
|
if (this.stickyColumn)
|
||||||
this.fixedColSizer.style.height = targetHeight+'px';
|
this.fixedColSizer.style.height = targetHeight+'px';
|
||||||
this.tableSizer.style.height = targetHeight+'px';
|
this.tableSizer.style.height = targetHeight+'px';
|
||||||
var scrollPos = targetHeight > offsetHeight ? scrollTop / (targetHeight - offsetHeight) : 0;
|
var scrollPos = targetHeight > offsetHeight ? scrollTop / (targetHeight - offsetHeight) : 0;
|
||||||
if (scrollPos > 1)
|
if (scrollPos > 1)
|
||||||
scrollPos = 1;
|
scrollPos = 1;
|
||||||
var firstVisible = scrollPos*lastFirst;
|
var firstVisible = scrollPos*this.lastFirstNodeIndex;
|
||||||
var rangeStart = Math.floor(firstVisible);
|
var rangeStart = Math.floor(firstVisible);
|
||||||
var rangeCount = visibleItems;
|
var rangeCount = visibleItems;
|
||||||
this._addPlaceholder('top', 0);
|
this._addPlaceholder('top', 0);
|
||||||
|
@ -560,13 +588,13 @@ TreeGrid.prototype.syncView = function()
|
||||||
{
|
{
|
||||||
rangeCount = endStart-rangeStart;
|
rangeCount = endStart-rangeStart;
|
||||||
}
|
}
|
||||||
var visibleNodes = this._findNodes(this.root, rangeStart, rangeCount);
|
var visibleNodes = this._findNodes(rangeStart, rangeCount);
|
||||||
this._renderNodes(visibleNodes);
|
this._renderNodes(visibleNodes);
|
||||||
this._syncStart(visibleNodes);
|
this._syncStart(visibleNodes);
|
||||||
this._addPlaceholder('mid', 0);
|
this._addPlaceholder('mid', 0);
|
||||||
firstItemHeight = getNodeHeight(visibleNodes[0])*(firstVisible-rangeStart);
|
firstItemHeight = getNodeHeight(visibleNodes[0])*(firstVisible-rangeStart);
|
||||||
}
|
}
|
||||||
this._setPlaceholder('top', scrollTop-firstItemHeight-headerHeight);
|
this._setPlaceholder('top', scrollTop - firstItemHeight);
|
||||||
}
|
}
|
||||||
else if (this.stickyColumn)
|
else if (this.stickyColumn)
|
||||||
{
|
{
|
||||||
|
@ -585,14 +613,29 @@ TreeGrid.prototype.syncView = function()
|
||||||
this.syncStickyRow();
|
this.syncStickyRow();
|
||||||
if (endStart > 0 && endStart > rangeStart+rangeCount)
|
if (endStart > 0 && endStart > rangeStart+rangeCount)
|
||||||
for (var i = 0; i < this.tbody.rows.length; i++)
|
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)
|
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)
|
TreeGrid.prototype.nodeOnHover = function(hover, ev)
|
||||||
{
|
{
|
||||||
ev = ev||window.event;
|
ev = ev||window.event;
|
||||||
|
|
Loading…
Reference in New Issue