kinda sorta working
This commit is contained in:
parent
3f9ca66e38
commit
7682015cda
|
@ -17,7 +17,7 @@
|
|||
|
||||
let i = -1
|
||||
|
||||
const createData = () => fixture.slice(0, 5).map(_ => ({
|
||||
const createData = () => fixture.slice(0, 20).map(_ => ({
|
||||
key: `${++i}`,
|
||||
props: _
|
||||
}))
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<:Window bind:scrollY='scrollY'/>
|
||||
<:Window bind:scrollY='scrollY' bind:innerHeight='innerHeight' />
|
||||
<div class="virtual-list" ref:node style="height: {{$height}}px;">
|
||||
<!-- <div class="virtual-list-viewport" ref:viewport></div> -->
|
||||
{{#each $virtualItems as virtualItem, virtualIndex}}
|
||||
{{#each $visibleItems as item, virtualIndex}}
|
||||
<VirtualListItem :component
|
||||
props="{{virtualItem.props}}"
|
||||
index="{{virtualItem.index}}"
|
||||
key="{{virtualItem.key}}"
|
||||
offset="{{item.offset}}"
|
||||
props="{{item.item.props}}"
|
||||
index="{{item.item.index}}"
|
||||
key="{{item.item.key}}"
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
@ -20,12 +21,25 @@
|
|||
|
||||
export default {
|
||||
oncreate() {
|
||||
console.log('scrollHeight', this.refs.node.scrollHeight)
|
||||
this.store.set({
|
||||
scrollHeight: this.refs.node.scrollHeight,
|
||||
})
|
||||
this.observe('innerHeight', innerHeight => {
|
||||
this.store.set({
|
||||
innerHeight: innerHeight
|
||||
})
|
||||
})
|
||||
this.observe('items', (items) => {
|
||||
this.store.set({'items': items})
|
||||
this.store.set({
|
||||
'items': items
|
||||
})
|
||||
})
|
||||
this.observe('scrollY', (scrollY) => {
|
||||
console.log('scrollY', scrollY)
|
||||
this.store.set({scrollTop: scrollY})
|
||||
this.store.set({
|
||||
scrollTop: scrollY
|
||||
})
|
||||
})
|
||||
},
|
||||
data: () => ({
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="virtual-list-item"
|
||||
ref:node
|
||||
style="transform: translate3d(0, {{itemOffset}}px, 0);"
|
||||
style="transform: translate3d(0, {{offset}}px, 0);"
|
||||
data-virtual-index="{{index}}"
|
||||
data-virtual-key="{{key}}"
|
||||
>
|
||||
|
@ -22,11 +22,6 @@
|
|||
itemHeights[this.get('key')] = this.refs.node.offsetHeight
|
||||
this.store.set({itemHeights: itemHeights})
|
||||
},
|
||||
computed: {
|
||||
itemOffset: ($itemOffsets, key) => {
|
||||
return $itemOffsets[key] || 0
|
||||
}
|
||||
},
|
||||
store: () => virtualListStore
|
||||
}
|
||||
</script>
|
|
@ -1,6 +1,8 @@
|
|||
import { Store } from 'svelte/store.js'
|
||||
import { splice } from 'svelte-extras'
|
||||
|
||||
const RENDER_BUFFER = 1000
|
||||
|
||||
class VirtualListStore extends Store {
|
||||
}
|
||||
|
||||
|
@ -9,7 +11,8 @@ VirtualListStore.prototype.splice = splice
|
|||
const virtualListStore = new VirtualListStore({
|
||||
items: [],
|
||||
itemHeights: {},
|
||||
scrollTop: 0
|
||||
scrollTop: 0,
|
||||
scrollHeight: 0
|
||||
})
|
||||
|
||||
virtualListStore.compute('virtualItems', ['items'], (items) => {
|
||||
|
@ -20,15 +23,29 @@ virtualListStore.compute('virtualItems', ['items'], (items) => {
|
|||
}))
|
||||
})
|
||||
|
||||
virtualListStore.compute('itemOffsets', ['virtualItems', 'itemHeights'], (virtualItems, itemHeights) => {
|
||||
let itemOffsets = {}
|
||||
let totalHeight = 0
|
||||
virtualListStore.compute('visibleItems',
|
||||
['virtualItems', 'scrollTop', 'height', 'itemHeights', 'innerHeight'],
|
||||
(virtualItems, scrollTop, height, itemHeights, innerHeight) => {
|
||||
let visibleItems = []
|
||||
let currentOffset = 0
|
||||
virtualItems.forEach(item => {
|
||||
let height = itemHeights[item.key] || 0
|
||||
itemOffsets[item.key] = totalHeight
|
||||
totalHeight += height
|
||||
console.log(item.key, 'scrollTop', scrollTop, 'currentOffset', currentOffset, 'innerHeight', innerHeight)
|
||||
if (
|
||||
((currentOffset < scrollTop) && (scrollTop - RENDER_BUFFER < currentOffset)) ||
|
||||
((currentOffset >= scrollTop) && (currentOffset < (scrollTop + innerHeight + RENDER_BUFFER)))
|
||||
) {
|
||||
console.log(' rendering', item)
|
||||
visibleItems.push({
|
||||
item: item,
|
||||
offset: currentOffset
|
||||
})
|
||||
} else {
|
||||
console.log('not rendering', item)
|
||||
}
|
||||
currentOffset += height
|
||||
})
|
||||
return itemOffsets
|
||||
return visibleItems
|
||||
})
|
||||
|
||||
virtualListStore.compute('height', ['virtualItems', 'itemHeights'], (virtualItems, itemHeights) => {
|
||||
|
|
Loading…
Reference in a new issue