Skip to content

Commit 070de45

Browse files
committed
Fix
1 parent 9457ef4 commit 070de45

15 files changed

+236
-740
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ Svelte implementation of vue library [vue-virtual-scroll-list](https://github.co
44

55
Virtualized scrolling for big lists
66

7-
Online demo: [Svelte repl](https://ru.svelte.dev/repl/eae82aab17b04420885851d58de50a2e?version=3.38.2)
7+
Online demo: [https://v1ack.github.io/svelte-virtual-scroll-list/](https://v1ack.github.io/svelte-virtual-scroll-list/)
8+
9+
[Simple example in Svelte REPL](https://ru.svelte.dev/repl/eae82aab17b04420885851d58de50a2e?version=3.38.2)
810

911
## Todo
1012

package.json

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
{
22
"name": "svelte-virtual-scroll-list",
33
"description": "Svelte lib for virtualizing lists",
4-
"version": "1.0.2",
4+
"author": {
5+
"name": "v1ack",
6+
"url": "https://github.com/v1ack"
7+
},
8+
"keywords": [
9+
"svelte",
10+
"virtual",
11+
"virtual-list",
12+
"virtual-scroll"
13+
],
14+
"version": "1.0.6",
515
"scripts": {
616
"build": "rollup -c rollup/rollup.config.js",
717
"build:dev": "rollup -c rollup/rollup.config.dev.js",
@@ -21,9 +31,12 @@
2131
"rollup-plugin-css-only": "^3.1.0",
2232
"rollup-plugin-livereload": "^2.0.0",
2333
"rollup-plugin-svelte": "^7.0.0",
24-
"sirv-cli": "^1.0.0"
34+
"sirv-cli": "^1.0.0",
35+
"svelte": "^3.0.0"
2536
},
26-
"dependencies": {
37+
"peerDependencies": {
2738
"svelte": "^3.0.0"
28-
}
39+
},
40+
"main": "index.js",
41+
"svelte": "index.js"
2942
}

src/Item.svelte

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
1414
onMount(() => {
1515
if (typeof ResizeObserver !== "undefined") {
16-
resizeObserver = new ResizeObserver(() => {
17-
dispatchSizeChange()
18-
})
16+
resizeObserver = new ResizeObserver(dispatchSizeChange)
1917
resizeObserver.observe(itemDiv)
2018
}
2119
})
@@ -27,13 +25,8 @@
2725
}
2826
})
2927
30-
function getCurrentSize() {
31-
return itemDiv ? itemDiv[shapeKey] : 0
32-
}
33-
34-
// tell parent current size identify by unqiue key
3528
function dispatchSizeChange() {
36-
dispatch("resize", {id: uniqueKey, size: getCurrentSize(), type})
29+
dispatch("resize", {id: uniqueKey, size: itemDiv ? itemDiv[shapeKey] : 0, type})
3730
}
3831
</script>
3932

src/VirtualScroll.svelte

Lines changed: 76 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script>
2-
import Virtual from "./vue/virtual"
2+
import Virtual from "./virtual"
33
import Item from "./Item.svelte"
44
import {createEventDispatcher, onDestroy, onMount} from "svelte"
55
@@ -30,64 +30,12 @@
3030
let shepherd
3131
const dispatch = createEventDispatcher()
3232
33-
onMount(() => {
34-
if (start) {
35-
scrollToIndex(start)
36-
} else if (offset) {
37-
scrollToOffset(offset)
38-
}
39-
40-
if (pageMode) {
41-
updatePageModeFront()
42-
43-
document.addEventListener("scroll", onScroll, {
44-
passive: false,
45-
})
46-
}
47-
})
48-
49-
onDestroy(() => {
50-
virtual.destroy()
51-
if (pageMode) {
52-
document.removeEventListener("scroll", onScroll)
53-
}
54-
})
55-
56-
function getUniqueIdFromDataSources() {
57-
return data.map((dataSource) => dataSource[key])
58-
}
59-
60-
function onItemResized({id, size, type}) {
61-
if (type === "item")
62-
virtual.saveSize(id, size)
63-
else {
64-
if (id === "header")
65-
virtual.updateParam("slotHeaderSize", size)
66-
else if (id === "footer")
67-
virtual.updateParam("slotFooterSize", size)
68-
69-
virtual.handleSlotSizeChange()
70-
}
33+
export function getSize(id) {
34+
return virtual.sizes.get(id)
7135
}
7236
73-
function onRangeChanged(range_) {
74-
range = range_
75-
paddingStyle = paddingStyle = isHorizontal ? `0px ${range.padBehind}px 0px ${range.padFront}px` : `${range.padFront}px 0px ${range.padBehind}px`
76-
displayItems = data.slice(range.start, range.end + 1)
77-
}
78-
79-
function onScroll(event) {
80-
const offset = getOffset()
81-
const clientSize = getClientSize()
82-
const scrollSize = getScrollSize()
83-
84-
// iOS scroll-spring-back behavior will make direction mistake
85-
if (offset < 0 || (offset + clientSize > scrollSize + 1) || !scrollSize) {
86-
return
87-
}
88-
89-
virtual.handleScroll(offset)
90-
emitEvent(offset, clientSize, scrollSize, event)
37+
export function getSizes() {
38+
return virtual.sizes.size
9139
}
9240
9341
export function getOffset() {
@@ -125,16 +73,6 @@
12573
}
12674
}
12775
128-
function emitEvent(offset, clientSize, scrollSize, event) {
129-
dispatch("scroll", {event, range: virtual.getRange()})
130-
131-
if (virtual.isFront() && !!data.length && (offset - topThreshold <= 0)) {
132-
dispatch("top")
133-
} else if (virtual.isBehind() && (offset + clientSize + bottomThreshold >= scrollSize)) {
134-
dispatch("bottom")
135-
}
136-
}
137-
13876
export function scrollToOffset(offset) {
13977
if (pageMode) {
14078
document.body[directionKey] = offset
@@ -145,7 +83,6 @@
14583
}
14684
14785
export function scrollToIndex(index) {
148-
// scroll to bottom
14986
if (index >= data.length - 1) {
15087
scrollToBottom()
15188
} else {
@@ -154,9 +91,6 @@
15491
}
15592
}
15693
157-
/**
158-
* set current scroll position to bottom
159-
*/
16094
export function scrollToBottom() {
16195
if (shepherd) {
16296
const offset = shepherd[isHorizontal ? "offsetLeft" : "offsetTop"]
@@ -173,6 +107,76 @@
173107
}
174108
}
175109
110+
onMount(() => {
111+
if (start) {
112+
scrollToIndex(start)
113+
} else if (offset) {
114+
scrollToOffset(offset)
115+
}
116+
117+
if (pageMode) {
118+
updatePageModeFront()
119+
120+
document.addEventListener("scroll", onScroll, {
121+
passive: false,
122+
})
123+
}
124+
})
125+
126+
onDestroy(() => {
127+
virtual.destroy()
128+
if (pageMode) {
129+
document.removeEventListener("scroll", onScroll)
130+
}
131+
})
132+
133+
function getUniqueIdFromDataSources() {
134+
return data.map((dataSource) => dataSource[key])
135+
}
136+
137+
function onItemResized({id, size, type}) {
138+
if (type === "item")
139+
virtual.saveSize(id, size)
140+
else {
141+
if (id === "header")
142+
virtual.updateParam("slotHeaderSize", size)
143+
else if (id === "footer")
144+
virtual.updateParam("slotFooterSize", size)
145+
146+
virtual.handleSlotSizeChange()
147+
}
148+
}
149+
150+
function onRangeChanged(range_) {
151+
range = range_
152+
paddingStyle = paddingStyle = isHorizontal ? `0px ${range.padBehind}px 0px ${range.padFront}px` : `${range.padFront}px 0px ${range.padBehind}px`
153+
displayItems = data.slice(range.start, range.end + 1)
154+
}
155+
156+
function onScroll(event) {
157+
const offset = getOffset()
158+
const clientSize = getClientSize()
159+
const scrollSize = getScrollSize()
160+
161+
// iOS scroll-spring-back behavior will make direction mistake
162+
if (offset < 0 || (offset + clientSize > scrollSize + 1) || !scrollSize) {
163+
return
164+
}
165+
166+
virtual.handleScroll(offset)
167+
emitEvent(offset, clientSize, scrollSize, event)
168+
}
169+
170+
function emitEvent(offset, clientSize, scrollSize, event) {
171+
dispatch("scroll", {event, range: virtual.getRange()})
172+
173+
if (virtual.isFront() && !!data.length && (offset - topThreshold <= 0)) {
174+
dispatch("top")
175+
} else if (virtual.isBehind() && (offset + clientSize + bottomThreshold >= scrollSize)) {
176+
dispatch("bottom")
177+
}
178+
}
179+
176180
$: scrollToOffset(offset)
177181
$: scrollToIndex(start)
178182
$: {
@@ -182,11 +186,8 @@
182186
$: handleDataSourcesChange(data)
183187
184188
async function handleDataSourcesChange(dataSources) {
185-
// TODO: fix jump on top added data
186-
console.log("data change")
187189
virtual.updateParam("uniqueIds", getUniqueIdFromDataSources())
188190
virtual.handleDataSourcesChange()
189-
onRangeChanged(range)
190191
}
191192
</script>
192193

@@ -197,7 +198,7 @@
197198
</Item>
198199
{/if}
199200
<div style="padding: {paddingStyle}">
200-
{#each displayItems as data}
201+
{#each displayItems as data (data[key])}
201202
<Item
202203
on:resize={(e) => onItemResized(e.detail)}
203204
uniqueKey={data[key]}
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,18 @@ const CALC_TYPE = {
1313
}
1414
const LEADING_BUFFER = 2
1515

16-
export default class Virtual {
16+
export default class {
17+
param
18+
callUpdate
19+
firstRangeTotalSize = 0
20+
firstRangeAverageSize = 0
21+
lastCalcIndex = 0
22+
fixedSizeValue = 0
23+
calcType = CALC_TYPE.INIT
24+
offset = 0
25+
direction = ""
26+
range
27+
1728
constructor(param, callUpdate) {
1829
this.init(param, callUpdate)
1930
}

0 commit comments

Comments
 (0)