forked from cybrespace/pinafore
start on infinite scrolling
This commit is contained in:
parent
5e3e56d454
commit
e670b57381
|
@ -1,6 +1,7 @@
|
|||
<div class="timeline">
|
||||
<VirtualList component="{{StatusListItem}}" items="{{statuses}}" />
|
||||
<button type="button" on:click="addMoreItems()">Add more items</button>
|
||||
<VirtualList component="{{StatusListItem}}"
|
||||
items="{{statuses}}"
|
||||
on:scrollToBottom="addMoreItems()" />
|
||||
</div>
|
||||
<style>
|
||||
.timeline {
|
||||
|
@ -17,7 +18,7 @@
|
|||
|
||||
let i = -1
|
||||
|
||||
const createData = () => fixture.slice(0, 20).map(_ => ({
|
||||
const createData = () => fixture.slice(0, 5).map(_ => ({
|
||||
key: `${++i}`,
|
||||
props: _
|
||||
}))
|
||||
|
@ -35,6 +36,7 @@
|
|||
methods: {
|
||||
splice: splice,
|
||||
addMoreItems() {
|
||||
console.log('addMoreItems')
|
||||
this.splice('statuses', this.get('statuses').length, 0, ...createData())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,15 @@
|
|||
import throttle from 'lodash/throttle'
|
||||
|
||||
const THROTTLE_TIME = 500
|
||||
const DISTANCE_FROM_BOTTOM_TO_FIRE = 400
|
||||
|
||||
export default {
|
||||
oncreate () {
|
||||
this.observe('innerHeight', throttle(innerHeight => {
|
||||
let container = document.body.querySelector('.container')
|
||||
this.observe('innerHeight', throttle(() => {
|
||||
// respond to window resize events
|
||||
this.store.set({
|
||||
innerHeight: innerHeight
|
||||
offsetHeight: container.offsetHeight
|
||||
})
|
||||
}, THROTTLE_TIME))
|
||||
this.observe('items', (items) => {
|
||||
|
@ -33,14 +36,27 @@
|
|||
'items': items
|
||||
})
|
||||
})
|
||||
document.body.querySelector('.container').addEventListener('scroll', throttle((e) => {
|
||||
this.store.observe('distanceFromBottom', distanceFromBottom => {
|
||||
console.log('distanceFromBottom', distanceFromBottom)
|
||||
if (distanceFromBottom >= 0 &&
|
||||
distanceFromBottom <= DISTANCE_FROM_BOTTOM_TO_FIRE) {
|
||||
this.fire('scrollToBottom')
|
||||
}
|
||||
})
|
||||
container.addEventListener('scroll', throttle((e) => {
|
||||
this.store.set({
|
||||
scrollTop: e.target.scrollTop
|
||||
scrollTop: e.target.scrollTop,
|
||||
scrollHeight: e.target.scrollHeight
|
||||
}, {
|
||||
leading: false,
|
||||
trailing: true
|
||||
})
|
||||
}, THROTTLE_TIME))
|
||||
this.store.set({
|
||||
scrollTop: container.scrollTop,
|
||||
scrollHeight: container.scrollHeight,
|
||||
offsetHeight: container.offsetHeight
|
||||
})
|
||||
},
|
||||
data: () => ({
|
||||
component: null
|
||||
|
|
|
@ -6,13 +6,12 @@ class VirtualListStore extends Store {
|
|||
const virtualListStore = new VirtualListStore({
|
||||
items: [],
|
||||
itemHeights: {},
|
||||
scrollTop: 0
|
||||
})
|
||||
|
||||
virtualListStore.compute('visibleItems',
|
||||
['items', 'scrollTop', 'height', 'itemHeights', 'innerHeight'],
|
||||
(items, scrollTop, height, itemHeights, innerHeight) => {
|
||||
let renderBuffer = 1.5 * innerHeight
|
||||
['items', 'scrollTop', 'itemHeights', 'offsetHeight'],
|
||||
(items, scrollTop, itemHeights, offsetHeight) => {
|
||||
let renderBuffer = 1.5 * offsetHeight
|
||||
let visibleItems = []
|
||||
let totalOffset = 0
|
||||
let len = items.length
|
||||
|
@ -28,7 +27,7 @@ virtualListStore.compute('visibleItems',
|
|||
continue // below the area we want to render
|
||||
}
|
||||
} else {
|
||||
if (currentOffset > (scrollTop + innerHeight + renderBuffer)) {
|
||||
if (currentOffset > (scrollTop + offsetHeight + renderBuffer)) {
|
||||
break // above the area we want to render
|
||||
}
|
||||
}
|
||||
|
@ -36,12 +35,24 @@ virtualListStore.compute('visibleItems',
|
|||
offset: currentOffset,
|
||||
props: props,
|
||||
key: key,
|
||||
index: i
|
||||
index: i,
|
||||
height: height
|
||||
})
|
||||
}
|
||||
return visibleItems
|
||||
})
|
||||
|
||||
virtualListStore.compute('distanceFromBottom',
|
||||
['scrollHeight', 'scrollTop', 'offsetHeight'],
|
||||
(scrollHeight, scrollTop, offsetHeight) => {
|
||||
if (typeof scrollHeight === 'undefined' ||
|
||||
typeof scrollTop === 'undefined' ||
|
||||
typeof offsetHeight === 'undefined') {
|
||||
return -1
|
||||
}
|
||||
return scrollHeight - scrollTop - offsetHeight
|
||||
})
|
||||
|
||||
virtualListStore.compute('height', ['items', 'itemHeights'], (items, itemHeights) => {
|
||||
let sum = 0
|
||||
let i = -1
|
||||
|
|
Loading…
Reference in New Issue