fix: 修复虚拟滚动快速滑动时内容丢失的问题,并为测试列表添加标题 (by AI)
This commit is contained in:
parent
08e448f845
commit
f8656f9afb
12
TEST.md
12
TEST.md
@ -3,12 +3,12 @@
|
|||||||
## 基准测试 (Benchmark)
|
## 基准测试 (Benchmark)
|
||||||
*测试环境: Playwright / Chromium*
|
*测试环境: Playwright / Chromium*
|
||||||
|
|
||||||
| 指标 | v1.0.0 | v1.0.1 | v1.0.3 |
|
| 指标 | v1.0.0 | v1.0.1 | v1.0.3 | v1.0.4 |
|
||||||
| :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- | :--- |
|
||||||
| **FastList Render & Scroll (10k items)** | ~535ms | ~473ms | ~1513ms |
|
| **FastList Render & Scroll (10k items)** | ~535ms | ~473ms | ~1513ms | ~54ms |
|
||||||
| **FastGroupedList Render & Scroll (10k)** | ~705ms | ~51ms | ~51ms |
|
| **FastGroupedList Render & Scroll (10k)** | ~705ms | ~51ms | ~51ms | ~1550ms |
|
||||||
| **FastTree Render & Scroll (10k items)** | ~927ms | ~50ms | ~51ms |
|
| **FastTree Render & Scroll (10k items)** | ~927ms | ~50ms | ~51ms | ~1560ms |
|
||||||
| **CollapseTree Render & Scroll (1.2k)** | ~51ms | ~50ms | ~50ms |
|
| **CollapseTree Render & Scroll (1.2k)** | ~51ms | ~50ms | ~50ms | ~51ms |
|
||||||
|
|
||||||
## 测试覆盖 (Coverage)
|
## 测试覆盖 (Coverage)
|
||||||
- [x] HTTP Request (GET/POST)
|
- [x] HTTP Request (GET/POST)
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@web/base",
|
"name": "@web/base",
|
||||||
"version": "1.0.3",
|
"version": "1.0.4", "type": "module",
|
||||||
"type": "module",
|
|
||||||
"main": "dist/base.js",
|
"main": "dist/base.js",
|
||||||
"module": "dist/base.js",
|
"module": "dist/base.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
15
src/list.js
15
src/list.js
@ -43,25 +43,28 @@ export const VirtualScroll = () => {
|
|||||||
},
|
},
|
||||||
calc: (container, list) => {
|
calc: (container, list) => {
|
||||||
if (!listInited || !list) return null;
|
if (!listInited || !list) return null;
|
||||||
const size = list.length, visibleCount = Math.ceil((container.clientHeight || 100) / (avg.get() || 32));
|
const size = list.length, visibleCount = Math.max(10, Math.ceil((container.clientHeight || 100) / (avg.get() || 32)));
|
||||||
let prev = padTop + topMargin + rowGap, post = 0, status = 0, listStartIndex = 0, listEndIndex = 0;
|
let prev = padTop + topMargin + rowGap, post = 0, status = 0, listStartIndex = 0, listEndIndex = 0;
|
||||||
|
const scrollTop = container.scrollTop;
|
||||||
|
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
if (status === 0) {
|
if (status === 0) {
|
||||||
const gh = groupHeights.get(i);
|
const gh = groupHeights.get(i);
|
||||||
if (gh && prev + gh < container.scrollTop) { prev += gh; i += Math.min(groupItemCount, size - i) - 1; }
|
if (gh && prev + gh < scrollTop && i + groupItemCount <= size) { prev += gh; i += groupItemCount - 1; }
|
||||||
else {
|
else {
|
||||||
const ih = itemHeights.get(i);
|
const ih = itemHeights.get(i);
|
||||||
if (prev + ih < container.scrollTop) prev += ih;
|
if (prev + ih < scrollTop && i < size - 1) prev += ih;
|
||||||
else {
|
else {
|
||||||
status = 1; let visibleStartIndex = Math.max(0, i);
|
status = 1; let visibleStartIndex = i;
|
||||||
listStartIndex = Math.max(0, visibleStartIndex - visibleCount);
|
listStartIndex = Math.max(0, visibleStartIndex - visibleCount);
|
||||||
listEndIndex = Math.min(listStartIndex + visibleCount * 3, size);
|
listEndIndex = Math.min(listStartIndex + visibleCount * 3, size);
|
||||||
i = listEndIndex - 1; for (let j = listStartIndex; j < visibleStartIndex; j++) prev -= itemHeights.get(j);
|
i = listEndIndex - 1; for (let j = listStartIndex; j < visibleStartIndex; j++) prev -= itemHeights.get(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (status === 1) {
|
} else {
|
||||||
const gh = groupHeights.get(i);
|
const gh = groupHeights.get(i);
|
||||||
if (gh) { post += gh; i += groupItemCount - 1; } else post += itemHeights.get(i);
|
if (gh && i + groupItemCount <= size) { post += gh; i += groupItemCount - 1; }
|
||||||
|
else post += itemHeights.get(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { prevHeight: Math.max(0, prev - padTop - topMargin - rowGap), postHeight: post, renderedList: list.slice(listStartIndex, listEndIndex), listStartIndex };
|
return { prevHeight: Math.max(0, prev - padTop - topMargin - rowGap), postHeight: post, renderedList: list.slice(listStartIndex, listEndIndex), listStartIndex };
|
||||||
|
|||||||
@ -28,17 +28,29 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<div class="d-flex flex-fill flex-wrap overflow-auto">
|
<div class="d-flex flex-fill flex-wrap overflow-auto">
|
||||||
<List fast id="ll" auto-select class="p-4 h-50 w-50 d-flex flex-column gap-3 bg-body-secondary rounded" $.state.list="list_data" $onitemclick="console.log(index, item)">
|
<div class="p-2 h-50 w-50 d-flex flex-column">
|
||||||
<template slot="item">
|
<h5>Fast List (Variable Height)</h5>
|
||||||
<div class="d-flex justify-content-center align-items-center border border-primary rounded" $text="item.label" $.style.height="${(item.index%10)*5+40}px"></div>
|
<List fast id="ll" auto-select class="flex-fill d-flex flex-column gap-3 bg-body-secondary rounded" $.state.list="list_data" $onitemclick="console.log(index, item)">
|
||||||
</template>
|
<template slot="item">
|
||||||
</List>
|
<div class="d-flex justify-content-center align-items-center border border-primary rounded" $text="item.label" $.style.height="${(item.index%10)*5+40}px"></div>
|
||||||
<List fast mode="group" id="gl" auto-select auto-select-group class="p-4 h-50 w-50 d-flex flex-column border border-info rounded" $.state.groups="group_list" $.state.list="list_data"
|
</template>
|
||||||
$ongroupclick="console.log(index, item)">
|
</List>
|
||||||
</List>
|
</div>
|
||||||
<List fast mode="tree" id="tt" auto-select class="p-4 h-50 w-50 d-flex flex-column border border-info rounded" $.state.list="list_data" $onitemclick="console.log(index, item)"></List>
|
<div class="p-2 h-50 w-50 d-flex flex-column">
|
||||||
<List mode="tree" collapsible id="ct" auto-select class="p-4 h-50 w-50 d-flex flex-column border border-info rounded" $.state.list="list_data.slice(0, 1200)" $onitemclick="console.log(index, item)">
|
<h5>Fast Grouped List</h5>
|
||||||
</List>
|
<List fast mode="group" id="gl" auto-select auto-select-group class="flex-fill d-flex flex-column border border-info rounded" $.state.groups="group_list" $.state.list="list_data"
|
||||||
|
$ongroupclick="console.log(index, item)">
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
<div class="p-2 h-50 w-50 d-flex flex-column">
|
||||||
|
<h5>Fast Tree List</h5>
|
||||||
|
<List fast mode="tree" id="tt" auto-select class="flex-fill d-flex flex-column border border-info rounded" $.state.list="list_data" $onitemclick="console.log(index, item)"></List>
|
||||||
|
</div>
|
||||||
|
<div class="p-2 h-50 w-50 d-flex flex-column">
|
||||||
|
<h5>Normal Tree List (Collapsible)</h5>
|
||||||
|
<List mode="tree" collapsible id="ct" auto-select class="flex-fill d-flex flex-column border border-info rounded" $.state.list="list_data.slice(0, 1200)" $onitemclick="console.log(index, item)">
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user