vitalif / dynamic-virtual-scroll

Render-agnostic Dynamic Virtual Scroll Driver for JS
38 stars 11 forks source link

Full page mode #4

Open nicolas-t opened 2 years ago

nicolas-t commented 2 years ago

Hello,

I'm working on a Vue implementation of your library. (I will open source it later) It's going pretty well in a container, but i'm trying to achieve the same behaviour in the full page, where the body is the viewport and the scroll event listener is attached to window.

I'm calling virtualScrollDriver like this :

      const bounds = document.querySelector("body").getBoundingClientRect();
      const scrollTop = -bounds.top;
      const viewportHeight = window.innerHeight;
      const newState = virtualScrollDriver(
        {
          totalItems: this.items.length,
          minRowHeight: 100,
          viewportHeight: viewportHeight,
          scrollTop: scrollTop,
        },
        this.scrollerState,
        this.getRenderedItemHeight
      );

It works well, until you have DOM elements in the body, before the list.

For example here, I have a <pre> tag before the list, and it disturbs the virtual scroll behaviour. image If you remove the <pre> tag (or change it's position to fixed) it fixes the bug.

You can play with the code here (it can take a while to load) : https://codesandbox.io/s/flamboyant-easley-ix9pe?file=/src/App.vue

How would you implement the full page mode when the list is not the only item the body ?

Also, not related to the full page mode, before any scroll happen, the lastItems are displayed: image

Thanks for your help.

vitalif commented 2 years ago

Hi

Also, not related to the full page mode, before any scroll happen, the lastItems are displayed:

That's because on the first pass your getRenderedItemHeight returns 0 and driver is not called again when the page is rendered. See componentDidUpdate in VirtualScrollDriver.js - it also calls driver(). The rest of this method relates to scrollToItem() so you don't strictly need it.

How would you implement the full page mode when the list is not the only item the body ?

I think it's similar to the "fixed header" in the sample http://yourcmc.ru/dynamic-virtual-scroll/. You should just subtract fixed header/footer sizes from the total viewport size.

nicolas-t commented 2 years ago

Hello,

Thanks for your answer :+1:

That's because on the first pass your getRenderedItemHeight returns 0 and driver is not called again when the page is rendered. See componentDidUpdate in VirtualScrollDriver.js - it also calls driver(). The rest of this method relates to scrollToItem() so you don't strictly need it.

Perfect :)

I think it's similar to the "fixed header" in the sample http://yourcmc.ru/dynamic-virtual-scroll/. You should just subtract fixed header/footer sizes from the total viewport size.

It's not exactly similar, because the topbar is not fixed, so once it's out of the viewport, we want the list items to fill the whole viewport. With the substract method there is a blank space were the header used to be before we scrolled it out of the viewport: image

Best regards,