Add fixed header to the example

master
Vitaliy Filippov 2018-10-09 15:14:53 +03:00
parent e9edd4d551
commit f417d1de71
2 changed files with 42 additions and 21 deletions

View File

@ -4,6 +4,8 @@ import { virtualScrollDriver } from './DynamicVirtualScroll.js';
export class DynamicVirtualScrollExample extends React.PureComponent
{
useFixedHeader = true
constructor()
{
super();
@ -51,23 +53,40 @@ export class DynamicVirtualScrollExample extends React.PureComponent
render()
{
this.itemElements = [];
return (<div style={{overflowY: 'scroll', height: '400px', width: '400px'}}
ref={e => this.viewport = e}
onScroll={this.componentDidUpdate}>
<div style={{height: this.state.targetHeight+'px'}}>
{this.state.topPlaceholderHeight
? <div style={{height: this.state.topPlaceholderHeight+'px'}}></div>
: null}
{this.state.middleItemCount
? this.renderItems(this.state.firstMiddleItem, this.state.middleItemCount)
: null}
{this.state.middlePlaceholderHeight
? <div style={{height: this.state.middlePlaceholderHeight+'px'}}></div>
: null}
{this.state.lastItemCount
? this.renderItems(this.state.items.length-this.state.lastItemCount, this.state.lastItemCount)
: null}
return (<div style={{position: 'relative', width: '400px'}}>
<div style={{overflowY: 'scroll', height: '400px', width: '400px'}}
ref={e => this.viewport = e}
onScroll={this.componentDidUpdate}>
<div style={{height: this.state.targetHeight+'px'}}>
{this.useFixedHeader
? <div style={{height: '30px'}}></div>
: null}
{this.state.topPlaceholderHeight
? <div style={{height: this.state.topPlaceholderHeight+'px'}}></div>
: null}
{this.state.middleItemCount
? this.renderItems(this.state.firstMiddleItem, this.state.middleItemCount)
: null}
{this.state.middlePlaceholderHeight
? <div style={{height: this.state.middlePlaceholderHeight+'px'}}></div>
: null}
{this.state.lastItemCount
? this.renderItems(this.state.items.length-this.state.lastItemCount, this.state.lastItemCount)
: null}
</div>
</div>
{this.useFixedHeader ? <div style={{
position: 'absolute',
top: 0,
left: 0,
right: this.state.scrollbarWidth+'px',
height: '30px',
background: '#0080c0',
color: 'white',
textAlign: 'center',
lineHeight: '30px'}}>
fixed header
</div> : null}
</div>);
}
@ -78,12 +97,13 @@ export class DynamicVirtualScrollExample extends React.PureComponent
{
totalItems: this.state.items.length,
minRowHeight: 30,
viewportHeight: this.viewport.clientHeight,
viewportHeight: this.viewport.clientHeight - (this.useFixedHeader ? 30 : 0),
scrollTop: this.viewport.scrollTop,
},
this.state,
this.getRenderedItemHeight
);
newState.scrollbarWidth = this.viewport ? this.viewport.offsetWidth-this.viewport.clientWidth : 12;
this.setStateIfDiffers(newState);
}

View File

@ -1,6 +1,6 @@
# Dynamic Virtual Scroll Driver
Virtual scrolling is a technique for displaying long lists when you render only a small number
Virtual scrolling is a technique for displaying long lists or tables when you render only a small number
of visible items and skip items that are offscreen. You may also have heard about it like
"buffered render" or "windowed render" - it's the same.
@ -17,8 +17,9 @@ UI component or framework and are unusable with other ones.
Good news, everyone: we have a solution!
It is render-agnostic and implemented in this library. Basically, this library only does the maths for you
while letting you render your component yourself. You can use it with React, Angular, pure JS or any other framework
you want to. It works smoothly, does not break built-in browser scrolling and even works on mobile devices.
while letting you render your component yourself. You can use it with React, Angular, pure JS or any other
framework you want to. You can implement lists and grids (tables) with it. It works smoothly, does not break
built-in browser scrolling and even works on mobile devices.
# Usage
@ -79,7 +80,7 @@ How to test it:
* Find maximum possible viewport start in units of (item number + % of item)
* Measure average height of last rows
* `avgHeight = max(minHeight, lastRowAvgHeight)`
* `targetHeight = avgHeight*rowCount + headerHeight`
* `targetHeight = avgHeight*rowCount`
* Total scroll view height will be `targetHeight`
* `scrollPos = targetHeight > offsetHeight ? min(1, scrollTop / (targetHeight - offsetHeight)) : 0`
* First visible item will be `Math.floor(scrollPos*maxPossibleViewportStart)`