vue-virtual-scroll-list
vue-virtual-scroll-list copied to clipboard
Empty space after source list array was changed
Sometimes, not always while source array is changing (add new item, delete existing item) the virtual-scroll-list isn't updating as result i see the blank space on div role=group

but after scrolling couple times it looks as it should
i have source list stored in vuex and updating it by mutations with Vue.set so it should be reactive
btw i made small demo but there it works as it should work, so i dunno where problem is. but sometimes either in demo this problem occurs. to reproduce it maybe height of messages should be completely different sizes. https://codesandbox.io/s/zen-kilby-8gnsq?file=/src/App.vue
but after scrolling couple times it looks as it should
This is a very strange and difficult problem to find out, can you try this.$forceUpdate() to see if problem occurs.
I can confirm this behavior.. It happends everytime when I use array push adding with scrollToBottom() method - with regular scenario - every second or third array push wont show. It doesn't happend when I have to scroll after adding manually (without using scrollToBottom or setting scrollTop). I think the frequency of blank space occurence (there is no listitem DOM element) depends on virtual list height. Scrolling helps because of listitem DOM re-loading. I'am using updatePageModeFront() after every array push - this.$forceUpdate() didn't help.
UPDATE - workaround - lets say that this.messages = source, chat example:
this.messages.push(payload) // add new item to array
this.$refs.chat.updatePageModeFront() // call for visual update
this.messages.push({
id: this.messages.length + 1,
message: '',
nickName: ''
}) // add another placeholder item, that prevent make blank space (IDK why.. but it works) - it wont appear because of v-if="nickName !== ' ' " in my component
setTimeout(() => {
this.messages.splice(-1, 1) // timeouted remove of last item
})
this.$refs.chat.scrollToBottom() // perform bottom scroll
It is not perfect, because this is not as smooth as native (you have to add empty item to array and then immediately remove it), but it works
I can confirm I have the same issue with a chat I made. My scenario is the same as @radimhornicek , though I'll probably use that workaround as a last resort.
This problem can be consistently reproduced in this infinite-loading demo https://tangbc.github.io/vue-virtual-scroll-list/#/infinite-loading by scrolling down and once it starts to load, scrolling a little bit back up again. At this time, the empty space occurs and will stay as is until you scroll down again (scrolling up won't update it).

Any updates?
in my case it was solution
const list = this.$refs.vList as InstanceType<typeof VirtualList>;
if (!list) return;
list.virtual.checkRange(0, list.keeps - 1);
I sometimes see a similar issue when I add a new item to the end of my list. I think it is due to handleDataSourcesChange which decides to not render the final few items due to isFront being true.
I don't know why it is checking isFront or isBehind because the new item was not added as a result of scrolling. It is just a new chat message that was received and added to the list of messages. The fact that it checks the scroll direction means I get different behaviour based on which direction I most recently scrolled in, which doesn't sound right.
For example, if the component is currently rendering items 20 to 79, then I add item 80 to the list, the handleDataSourcesChange function will decide to render items 18 to 77 even though I am not doing any scrolling:
handleDataSourcesChange () {
let start = this.range.start
if (this.isFront()) {
start = start - LEADING_BUFFER
} else if (this.isBehind()) {
start = start + LEADING_BUFFER
}
start = Math.max(start, 0)
this.updateRange(this.range.start, this.getEndByStart(start))
}