kinda working better

This commit is contained in:
Nolan Lawson 2018-01-15 16:35:08 -08:00
parent 21a2b4251e
commit 1528d51290
4 changed files with 35 additions and 37 deletions

View file

@ -25,11 +25,12 @@
<script> <script>
export default { export default {
computed: { computed: {
imagePromise: (account) => new Promise((resolve, reject) => { imageSrc: (account) => account.avatar,
imagePromise: (imageSrc) => new Promise((resolve, reject) => {
let img = new Image() let img = new Image()
img.onload = resolve img.onload = resolve
img.onerror = reject img.onerror = reject
img.src = account.avatar img.src = imageSrc
}) })
} }
} }

View file

@ -1,12 +1,12 @@
<:Window bind:scrollY='scrollY' bind:innerHeight='innerHeight' /> <:Window bind:scrollY='scrollY' bind:innerHeight='innerHeight' />
<div class="virtual-list" ref:node style="height: {{$height}}px;"> <div class="virtual-list" ref:node style="height: {{$height}}px;">
<!-- <div class="virtual-list-viewport" ref:viewport></div> --> <!-- <div class="virtual-list-viewport" ref:viewport></div> -->
{{#each $visibleItems as item, virtualIndex}} {{#each $visibleItems as item, index @key}}
<VirtualListItem :component <VirtualListItem :component
offset="{{item.offset}}" offset="{{item.offset}}"
props="{{item.item.props}}" props="{{item.props}}"
index="{{item.item.index}}" key="{{item.key}}"
key="{{item.item.key}}" index="{{item.index}}"
/> />
{{/each}} {{/each}}
</div> </div>
@ -18,29 +18,28 @@
<script> <script>
import VirtualListItem from './VirtualListItem' import VirtualListItem from './VirtualListItem'
import { virtualListStore } from '../_utils/virtualListStore' import { virtualListStore } from '../_utils/virtualListStore'
import debounce from 'lodash/debounce'
export default { export default {
oncreate() { oncreate() {
console.log('scrollHeight', this.refs.node.scrollHeight)
this.store.set({
scrollHeight: this.refs.node.scrollHeight,
})
this.observe('innerHeight', innerHeight => { this.observe('innerHeight', innerHeight => {
console.log('setting innerHeight', innerHeight)
this.store.set({ this.store.set({
innerHeight: innerHeight innerHeight: innerHeight
}) })
}) })
this.observe('items', (items) => { this.observe('items', (items) => {
console.log('setting items')
this.store.set({ this.store.set({
'items': items 'items': items
}) })
}) })
this.observe('scrollY', (scrollY) => { this.observe('scrollY', debounce((scrollY) => {
console.log('scrollY', scrollY) console.log('setting scrollY', scrollY)
this.store.set({ this.store.set({
scrollTop: scrollY scrollTop: scrollY
}) })
}) }, 2000))
}, },
data: () => ({ data: () => ({
component: null component: null

View file

@ -1,8 +1,8 @@
<div class="virtual-list-item" <div class="virtual-list-item"
ref:node ref:node
style="transform: translate3d(0, {{offset}}px, 0);" style="transform: translate3d(0, {{offset}}px, 0);"
data-virtual-index="{{index}}"
data-virtual-key="{{key}}" data-virtual-key="{{key}}"
data-virtual-index="{{index}}"
> >
<:Component {component} virtualProps="{{props}}" /> <:Component {component} virtualProps="{{props}}" />
</div> </div>
@ -18,9 +18,13 @@
export default { export default {
oncreate() { oncreate() {
'VirtualListItem: oncreate'
let itemHeights = this.store.get('itemHeights') let itemHeights = this.store.get('itemHeights')
itemHeights[this.get('key')] = this.refs.node.offsetHeight let key = this.get('key')
this.store.set({itemHeights: itemHeights}) itemHeights[key] = this.refs.node.offsetHeight
this.store.set({
itemHeights: itemHeights
})
}, },
store: () => virtualListStore store: () => virtualListStore
} }

View file

@ -8,46 +8,40 @@ class VirtualListStore extends Store {
const virtualListStore = new VirtualListStore({ const virtualListStore = new VirtualListStore({
items: [], items: [],
itemHeights: {}, itemHeights: {},
scrollTop: 0, scrollTop: 0
scrollHeight: 0
})
virtualListStore.compute('virtualItems', ['items'], (items) => {
return items.map((item, idx) => ({
props: item.props,
key: item.key,
index: idx
}))
}) })
virtualListStore.compute('visibleItems', virtualListStore.compute('visibleItems',
['virtualItems', 'scrollTop', 'height', 'itemHeights', 'innerHeight'], ['items', 'scrollTop', 'height', 'itemHeights', 'innerHeight'],
(virtualItems, scrollTop, height, itemHeights, innerHeight) => { (items, scrollTop, height, itemHeights, innerHeight) => {
let visibleItems = [] let visibleItems = []
let currentOffset = 0 let currentOffset = 0
virtualItems.forEach(item => { items.forEach((item, index) => {
let height = itemHeights[item.key] || 0 let { props, key } = item
console.log(item.key, 'scrollTop', scrollTop, 'currentOffset', currentOffset, 'innerHeight', innerHeight) let height = itemHeights[key] || 0
console.log(key, 'scrollTop', scrollTop, 'currentOffset', currentOffset, 'innerHeight', innerHeight)
if ( if (
((currentOffset < scrollTop) && (scrollTop - RENDER_BUFFER < currentOffset)) || ((currentOffset < scrollTop) && (scrollTop - RENDER_BUFFER < currentOffset)) ||
((currentOffset >= scrollTop) && (currentOffset < (scrollTop + innerHeight + RENDER_BUFFER))) ((currentOffset >= scrollTop) && (currentOffset < (scrollTop + innerHeight + RENDER_BUFFER)))
) { ) {
console.log(' rendering', item) console.log(' rendering', key)
visibleItems.push({ visibleItems.push({
item: item, offset: currentOffset,
offset: currentOffset props: props,
key: key,
index: index
}) })
} else { } else {
console.log('not rendering', item) console.log('not rendering', key)
} }
currentOffset += height currentOffset += height
}) })
return visibleItems return visibleItems
}) })
virtualListStore.compute('height', ['virtualItems', 'itemHeights'], (virtualItems, itemHeights) => { virtualListStore.compute('height', ['items', 'itemHeights'], (items, itemHeights) => {
let sum = 0 let sum = 0
virtualItems.forEach(item => { items.forEach(item => {
sum += itemHeights[item.key] || 0 sum += itemHeights[item.key] || 0
}) })
return sum return sum