Skip to content

Commit

Permalink
feat(VirtualList): add API jumpIndex
Browse files Browse the repository at this point in the history
  • Loading branch information
youluna committed Nov 26, 2018
1 parent a2b724d commit 2d137e2
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 27 deletions.
33 changes: 19 additions & 14 deletions docs/virtual-list/demo/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,23 @@ import { VirtualList } from '@alifd/next';

const dataSource = [];

const generateLi = (num, prefix = 'prefix') => {
const generateLi = (index = 'index') => {
const data = [];
for (let i = 0; i < num; i++) {
if (prefix % 3 === 0) {
data.push(<li key={`${i}-${prefix}`} style={{lineHeight: '20px'}}>{i}-{prefix}</li>);
} else {
data.push(<li key={`${i}-${prefix}`} style={{lineHeight: '30px'}}>{i}-{prefix}</li>);
}
if (index % 3 === 0) {
return <li key={`key-${index}`} style={{lineHeight: '30px', background: '#5f83ff', color: '#fff'}}>key-{index}</li>;
} else {
return <li key={`key-${index}`} style={{lineHeight: '20px'}}>key-{index}</li>;
}

return data;
};

for (let i = 0; i < 1000; i++) {
dataSource.push(generateLi(1, i));
dataSource.push(generateLi(i));
}

console.log(dataSource)
const getHeight = index => index % 3 === 0 ? 20 : 30;

const demo = (
<div className={'test'}>
<div className={'virtual-box'}>
<VirtualList>
{dataSource}
</VirtualList>
Expand All @@ -51,11 +48,19 @@ ReactDOM.render(demo, mountNode);
````

````css
.test {
.virtual-box {
height: 200px;
width: 200px;
border: 1px solid #ddd;
overflow: auto;
list-style-type: none;
}
.virtual-box ul {
padding: 0;
margin: 0;
list-style: none;
}
.virtual-box li {
padding-left: 10px;
border-bottom: 1px solid #333;
}
````
92 changes: 92 additions & 0 deletions docs/virtual-list/demo/initial-index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# 设置初始位置

- order: 0

使用 jumpIndex 设置初始位置

:::lang=en-us
# Basic

- order: 0

Use jumpIndex to set first item.

:::

---

````jsx
import { VirtualList } from '@alifd/next';

const dataSource = [];

function generateLi(index) {
if (index % 3 === 0) {
return (<li key={`key-${index}`} style={{lineHeight: '30px', background: '#5f83ff', color: '#fff'}}>key-{index}</li>);
} else {
return (<li key={`key-${index}`} style={{lineHeight: '20px'}}>key-{index}</li>);
}
}
function generateData(len) {
for (let i = 0; i < len; i++) {
dataSource.push(generateLi(i));
}
}

class App extends React.Component {
state = {
initial: 20,
dataSource: generateData(1000)
}
componentDidMount() {
setTimeout(()=> {
const instance = this.refs.virtual.getInstance();
instance.scrollTo(50);
}, 200);

}

getHeight(index) {
return index % 3 === 0 ? 30 : 20;
}
onClick() {
this.setState({
initial: this.state.initial + 20
})
}
render() {
return (
<div>
<button onClick={this.onClick.bind(this)}>jump to {this.state.initial + 20}</button>
<br/>
<br/>
<div className={'virtual-box'}>
<VirtualList ref="virtual" jumpIndex={this.state.initial} itemSizeGetter={this.getHeight.bind(this)}>
{dataSource}
</VirtualList>
</div>
</div>
);
}
}

ReactDOM.render(<App />, mountNode);
````

````css
.virtual-box {
height: 200px;
width: 200px;
border: 1px solid #ddd;
overflow: auto;
}
.virtual-box ul {
padding: 0;
margin: 0;
list-style: none;
}
.virtual-box li {
padding-left: 10px;
border-bottom: 1px solid #333;
}
````
4 changes: 3 additions & 1 deletion docs/virtual-list/index.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@
| children | child node to be rendered | any | - |
| minSize | min count of items to be loaded | Number | 1 |
| pageSize | the number of items in one page | Number | 10 |
| itemsRenderer | items parent dom,by default (items, ref) => <ul ref={ref}>{items}</ul><br><br>**签名**:<br>Function() => void | Function | (items, ref) => &lt;ul ref={ref}>{items}&lt;/ul> |
| itemsRenderer | items parent dom,by default (items, ref) => <ul ref={ref}>{items}</ul><br><br>**signature**:<br>Function() => void | Function | (items, ref) => &lt;ul ref={ref}>{items}&lt;/ul> |
| threshold | height of threshold | Number | 100 |
| itemSizeGetter | get item's height<br><br>**signature**:<br>Function() => void | Function | - |
| jumpIndex | set this to jump to the index you want, works only when you set itemSizeGetter | Number | 0 |
16 changes: 9 additions & 7 deletions docs/virtual-list/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@

### VirtualList

| 参数 | 说明 | 类型 | 默认值 |
| ------------- | ----------------------------------------------------------------------------------------- | -------- | ------------------------------------------------ |
| children | 渲染的子节点 | any | - |
| minSize | 最小加载数量 | Number | 1 |
| pageSize | 一屏数量 | Number | 10 |
| itemsRenderer | 父渲染函数,默认为 (items, ref) => <ul ref={ref}>{items}</ul><br><br>**签名**:<br>Function() => void | Function | (items, ref) => &lt;ul ref={ref}>{items}&lt;/ul> |
| threshold | 缓冲区高度 | Number | 100 |
| 参数 | 说明 | 类型 | 默认值 |
| -------------- | ----------------------------------------------------------------------------------------- | -------- | ------------------------------------------------ |
| children | 渲染的子节点 | any | - |
| minSize | 最小加载数量 | Number | 1 |
| pageSize | 一屏数量 | Number | 10 |
| itemsRenderer | 父渲染函数,默认为 (items, ref) => <ul ref={ref}>{items}</ul><br><br>**签名**:<br>Function() => void | Function | (items, ref) => &lt;ul ref={ref}>{items}&lt;/ul> |
| threshold | 缓冲区高度 | Number | 100 |
| itemSizeGetter | 获取item高度的函数<br><br>**签名**:<br>Function() => void | Function | - |
| jumpIndex | 设置初始位置,需要设置 itemSizeGetter 才能生效 | Number | 0 |
39 changes: 34 additions & 5 deletions src/virtual-list/virtual-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ export default class VirtualList extends Component {
* 缓冲区高度
*/
threshold: PropTypes.number,
/**
* 获取item高度的函数
*/
itemSizeGetter: PropTypes.func,
/**
* 设置跳转位置,需要设置 itemSizeGetter 才能生效
*/
jumpIndex: PropTypes.number,
className: PropTypes.string
};

Expand All @@ -51,32 +59,47 @@ export default class VirtualList extends Component {
itemsRenderer: (items, ref) => <ul ref={ref}>{items}</ul>,
minSize: 1,
pageSize: 10,
jumpIndex: 0,
threshold: 100
};

constructor(props) {
super(props);
const {from, size} = this.constrain(0, 0, props);
this.state = {from, size};
const { jumpIndex } = props;
const { from, size } = this.constrain(jumpIndex, 0, props);
this.state = { from, size};
this.cache = {};
this.scrollTo = this.scrollTo.bind(this);
this.cachedScroll = null;
this.unstable = false;
this.updateCounter = 0;
}

componentDidMount() {
const { jumpIndex } = this.props;

this.updateFrameAndClearCache = this.updateFrameAndClearCache.bind(this);

events.on(window, 'resize', this.updateFrameAndClearCache);
this.updateFrame(this.scrollTo.bind(this, 0));

this.updateFrame(this.scrollTo.bind(this, jumpIndex));
}

componentWillReceiveProps(next) {
const {from, size} = this.state;

const oldIndex = this.props.jumpIndex;
const newIndex = next.jumpIndex;

if (oldIndex !== newIndex) {
this.updateFrame(this.scrollTo.bind(this, newIndex));
}

this.maybeSetState(this.constrain(from, size, next), NOOP);
}

componentDidUpdate() {

// If the list has reached an unstable state, prevent an infinite loop.
if (this.unstable) {
return;
Expand Down Expand Up @@ -232,7 +255,9 @@ export default class VirtualList extends Component {
}

updateVariableFrame(cb) {
this.cacheSizes();
if (!this.props.itemSizeGetter) {
this.cacheSizes();
}

const {start, end} = this.getStartAndEnd();
const {pageSize, children} = this.props;
Expand Down Expand Up @@ -312,11 +337,15 @@ export default class VirtualList extends Component {
}

getSizeOf(index) {
const {cache} = this;
const { cache } = this;
const { itemSizeGetter } = this.props;
// Try the cache.
if (index in cache) {
return cache[index];
}
if (itemSizeGetter) {
return itemSizeGetter(index);
}
}

constrain(from, size, {children, minSize}) {
Expand Down

0 comments on commit 2d137e2

Please sign in to comment.