|
|
|
@ -9,7 +9,7 @@
|
|
|
|
有的特殊场景我们不能分页,只能渲染一个长列表。这个长列表中可能有几万条数据,如果全部渲染到页面上用户的设备差点可能就会直接卡死了,这时我们就需要虚拟列表来解决问题。
|
|
|
|
有的特殊场景我们不能分页,只能渲染一个长列表。这个长列表中可能有几万条数据,如果全部渲染到页面上用户的设备差点可能就会直接卡死了,这时我们就需要虚拟列表来解决问题。
|
|
|
|
|
|
|
|
|
|
|
|
一个常见的虚拟列表是下面这样的,如下图:
|
|
|
|
一个常见的虚拟列表是下面这样的,如下图:
|
|
|
|

|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
其中实线框的item表示在视口区域内真实渲染DOM,虚线框的item表示并没有渲染的DOM。
|
|
|
|
其中实线框的item表示在视口区域内真实渲染DOM,虚线框的item表示并没有渲染的DOM。
|
|
|
|
|
|
|
|
|
|
|
|
@ -119,19 +119,19 @@ function handleScroll(e) {
|
|
|
|
如果当前`itemSize`的值为100。
|
|
|
|
如果当前`itemSize`的值为100。
|
|
|
|
|
|
|
|
|
|
|
|
如果此时滚动的距离在0-100之间,比如下面这样:
|
|
|
|
如果此时滚动的距离在0-100之间,比如下面这样:
|
|
|
|

|
|
|
|

|
|
|
|
上面这张图item1还没完全滚出可视区域,有部分在可视区域内,部分在可视区域外。此时可视区域内显示的就是`item1-item7`的模块了,这就是为什么前面我们计算end时要多渲染一个item,不然这里item7就没法显示了。
|
|
|
|
上面这张图item1还没完全滚出可视区域,有部分在可视区域内,部分在可视区域外。此时可视区域内显示的就是`item1-item7`的模块了,这就是为什么前面我们计算end时要多渲染一个item,不然这里item7就没法显示了。
|
|
|
|
|
|
|
|
|
|
|
|
**滚动距离在0-100之间时,渲染的DOM没有变化,我们完全是复用浏览器的滚动,并没有进行任何处理。**
|
|
|
|
**滚动距离在0-100之间时,渲染的DOM没有变化,我们完全是复用浏览器的滚动,并没有进行任何处理。**
|
|
|
|
|
|
|
|
|
|
|
|
当`scrollTop`的值为100时,也就是刚刚把item1滚到可视区外面时。此时item1已经不需要渲染了,因为已经看不见他了。所以此时的`start`的值就应该从`0`更新为`1`,同理如果`scrollTop`的值为`110`,start的值也一样是`1`。所以得出`start.value = Math.floor(scrollTop / itemSize);`如下图:
|
|
|
|
当`scrollTop`的值为100时,也就是刚刚把item1滚到可视区外面时。此时item1已经不需要渲染了,因为已经看不见他了。所以此时的`start`的值就应该从`0`更新为`1`,同理如果`scrollTop`的值为`110`,start的值也一样是`1`。所以得出`start.value = Math.floor(scrollTop / itemSize);`如下图:
|
|
|
|

|
|
|
|

|
|
|
|
此时的`start`从item2开始渲染,但是由于前面我们复用了浏览器的滚动,所以实际渲染的DOM第一个已经在可视区外面了。此时可视区看见的第一个是item3,很明显是不对的,应该看见的是第一个是item2。
|
|
|
|
此时的`start`从item2开始渲染,但是由于前面我们复用了浏览器的滚动,所以实际渲染的DOM第一个已经在可视区外面了。此时可视区看见的第一个是item3,很明显是不对的,应该看见的是第一个是item2。
|
|
|
|
|
|
|
|
|
|
|
|
此时应该怎么办呢?
|
|
|
|
此时应该怎么办呢?
|
|
|
|
|
|
|
|
|
|
|
|
很简单,使用`translate`将列表向下偏移一个item的高度就行,也就是100px。列表偏移后就是下面这样的了:
|
|
|
|
很简单,使用`translate`将列表向下偏移一个item的高度就行,也就是100px。列表偏移后就是下面这样的了:
|
|
|
|

|
|
|
|

|
|
|
|
如果当前`scrollTop`的值为200,那么偏移值就是200px。所以我们得出
|
|
|
|
如果当前`scrollTop`的值为200,那么偏移值就是200px。所以我们得出
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
```javascript
|
|
|
|
@ -145,7 +145,7 @@ offset.value = scrollTop - (scrollTop % itemSize);
|
|
|
|
实际上从一个item滚动到另外一个item时,比如从`item0`滚动到`item1`。此时会做两件事情:将`start`的值从`0`更新为`1`和根据`scrollTop`计算得到列表的偏移值`100`,从而让新的start对应的`item1`重新回到可视范围内。
|
|
|
|
实际上从一个item滚动到另外一个item时,比如从`item0`滚动到`item1`。此时会做两件事情:将`start`的值从`0`更新为`1`和根据`scrollTop`计算得到列表的偏移值`100`,从而让新的start对应的`item1`重新回到可视范围内。
|
|
|
|
|
|
|
|
|
|
|
|
这个是运行效果图:
|
|
|
|
这个是运行效果图:
|
|
|
|

|
|
|
|

|
|
|
|
下面是完整的代码:
|
|
|
|
下面是完整的代码:
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
```javascript
|
|
|
|
|