try to get this feature working

This commit is contained in:
Nolan Lawson 2018-01-28 22:50:14 -08:00
parent ad443af5cd
commit 2f8400fe4e
3 changed files with 25 additions and 11 deletions

View File

@ -1,5 +1,5 @@
<!-- TODO: setting height is hacky, just make this element the scroller --> <!-- TODO: setting height is hacky, just make this element the scroller -->
<div class="virtual-list {{shown ? '' : 'hidden'}}" style="height: {{$height}}px;"> <div ref:node class="virtual-list {{shown ? '' : 'hidden'}}" style="height: {{$height}}px;">
{{#each $visibleItems as visibleItem @key}} {{#each $visibleItems as visibleItem @key}}
<VirtualListLazyItem :component <VirtualListLazyItem :component
offset="{{visibleItem.offset}}" offset="{{visibleItem.offset}}"
@ -33,6 +33,7 @@
this.fireScrollToBottom = throttle(() => { this.fireScrollToBottom = throttle(() => {
this.fire('scrollToBottom') this.fire('scrollToBottom')
}, SCROLL_TO_BOTTOM_DELAY) }, SCROLL_TO_BOTTOM_DELAY)
let node = this.refs.node
this.observe('showFooter', showFooter => { this.observe('showFooter', showFooter => {
this.store.setForRealm({showFooter: showFooter}) this.store.setForRealm({showFooter: showFooter})
}) })
@ -43,6 +44,10 @@
}) })
this.observe('scrollToItem', (scrollToItem) => { this.observe('scrollToItem', (scrollToItem) => {
mark('scrollToItem') mark('scrollToItem')
if (scrollToItem && node && !this.store.get('virtualListTop')) {
// have to calculate difference between container and virtual list tops in order to scroll
this.store.set({virtualListTop: node.getBoundingClientRect().top})
}
this.store.setForRealm({scrollToItem: scrollToItem}) this.store.setForRealm({scrollToItem: scrollToItem})
stop('scrollToItem') stop('scrollToItem')
}) })

View File

@ -19,6 +19,14 @@
let node = this.refs.node let node = this.refs.node
let realm = this.get('realm') let realm = this.get('realm')
this.store.set({currentRealm: realm}) this.store.set({currentRealm: realm})
this.observe('scrollToItem', scrollToItem => {
if (scrollToItem && node && !this.store.get('containerTop')) {
// have to calculate difference between container and virtual list tops in order to scroll
this.store.set({containerTop: node.getBoundingClientRect().top})
}
})
let scrollTop = this.store.get('scrollTop') let scrollTop = this.store.get('scrollTop')
if (scrollTop > 0) { if (scrollTop > 0) {
this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => { this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
@ -27,7 +35,7 @@
this.set({'initializedScrollTop': true}) this.set({'initializedScrollTop': true})
requestAnimationFrame(() => { requestAnimationFrame(() => {
mark('set scrollTop') mark('set scrollTop')
console.log('forcing scroll top to ', scrollTop) console.log('forcing scrollTop to ', scrollTop)
node.scrollTop = scrollTop node.scrollTop = scrollTop
stop('set scrollTop') stop('set scrollTop')
}) })
@ -44,7 +52,7 @@
this.set({'initializedScrollTop': true}) this.set({'initializedScrollTop': true})
requestAnimationFrame(() => { requestAnimationFrame(() => {
mark('set scrollToItemOffset') mark('set scrollToItemOffset')
console.log('forcing scroll top to ', scrollToItemOffset) console.log('forcing scrollItemOffset to ', scrollToItemOffset)
node.scrollTop = scrollToItemOffset node.scrollTop = scrollToItemOffset
stop('set scrollToItemOffset') stop('set scrollToItemOffset')
}) })
@ -89,6 +97,7 @@
}, },
methods: { methods: {
onScroll(event) { onScroll(event) {
console.log('onScroll', event.target.scrollTop)
this.store.setForRealm({ this.store.setForRealm({
scrollTop: event.target.scrollTop, scrollTop: event.target.scrollTop,
scrollHeight: event.target.scrollHeight scrollHeight: event.target.scrollHeight
@ -104,7 +113,8 @@
computed: { computed: {
// TODO: bug in svelte/store the observer in oncreate() never get removed without this hack // TODO: bug in svelte/store the observer in oncreate() never get removed without this hack
allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight, allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight,
scrollToItemOffset: ($scrollToItemOffset) => $scrollToItemOffset scrollToItemOffset: ($scrollToItemOffset) => $scrollToItemOffset,
scrollToItem: ($scrollToItem) => $scrollToItem
} }
}; };
</script> </script>

View File

@ -92,12 +92,11 @@ virtualListStore.compute('visibleItems',
let currentOffset = totalOffset let currentOffset = totalOffset
totalOffset += height totalOffset += height
if (!itemsLeftToCalculateHeight) { if (!itemsLeftToCalculateHeight) {
let isBelowViewport = (currentOffset < scrollTop) if (currentOffset < scrollTop) { // below viewport
if (!isBelowViewport) {
if (scrollTop - renderBuffer > currentOffset) { if (scrollTop - renderBuffer > currentOffset) {
continue // below the area we want to render continue // below the area we want to render
} }
} else { } else { // above or inside viewport
if (currentOffset > (scrollTop + height + renderBuffer)) { if (currentOffset > (scrollTop + height + renderBuffer)) {
break // above the area we want to render break // above the area we want to render
} }
@ -171,9 +170,9 @@ virtualListStore.compute('itemsLeftToCalculateHeight',
}) })
virtualListStore.compute('scrollToItemOffset', virtualListStore.compute('scrollToItemOffset',
['mustCalculateAllItemHeights', 'itemsLeftToCalculateHeight', 'scrollToItem', 'items', 'itemHeights'], ['mustCalculateAllItemHeights', 'itemsLeftToCalculateHeight', 'scrollToItem', 'items', 'itemHeights', 'containerTop', 'virtualListTop'],
(mustCalculateAllItemHeights, itemsLeftToCalculateHeight, scrollToItem, items, itemHeights) => { (mustCalculateAllItemHeights, itemsLeftToCalculateHeight, scrollToItem, items, itemHeights, containerTop, virtualListTop) => {
if (!mustCalculateAllItemHeights || itemsLeftToCalculateHeight) { if (!mustCalculateAllItemHeights || itemsLeftToCalculateHeight || !containerTop || !virtualListTop) {
return null return null
} }
let offset = 0 let offset = 0
@ -183,7 +182,7 @@ virtualListStore.compute('scrollToItemOffset',
} }
offset += itemHeights[item] offset += itemHeights[item]
} }
return offset return offset + (virtualListTop - containerTop) // have to offset difference between container and virtual list
}) })