tbranyen / hyperlist

A performant virtual scrolling list utility capable of rendering millions of rows
Other
450 stars 45 forks source link

Scrollto Item and Lazy item load #48

Open nevf opened 6 years ago

nevf commented 6 years ago

Let's say I have 500 items and I want to scroll to item 225 how would I do that?

Also is it possible to lazyload items? For example data that comes from a server. And relating this to my first question I'd only want retrieve to 30 or so items around item 225, not all items up unto item 225.

Thanks.

stevenvachon commented 5 years ago

Scrolling to item 225 would probably be:

const hyperlist = new HyperList(element, …);

element.scrollTo(hyperlist._itemPositions[225]);
timavaza commented 5 years ago

+1 this would be amazing to have

On Fri, May 10, 2019 at 6:46 PM Steven Vachon notifications@github.com wrote:

Probably:

const hyperlist = new HyperList(element, …);

element.scrollTo(hyperlist._itemPositions[i]);

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/tbranyen/hyperlist/issues/48#issuecomment-491335829, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ2SWSMB4DS4VME3XT3FHFTPUWKFBANCNFSM4FEYGLEA .

stevenvachon commented 5 years ago

I think the best way to implement a scroll-to feature would be for its method to take index and behavior arguments, add the corresponding element to the DOM regardless of scroll position, and finally scroll to it with scrollIntoView({behavior}). This would support CSS snap points and smooth scrolling.

razvangeangu commented 5 years ago

Use the scrollTop property of the container to set the position of the item.

scrollTo (index) {
  this._element.scrollTop = this._itemPositions[index];
}
stevenvachon commented 5 years ago

@razvangeangu how is that different from scrollTo (above) ?

razvangeangu commented 5 years ago

Just noticed it, but I think it should've been

element.scrollTo(0, hyperlist._itemPositions[225]);
lsmenicucci commented 1 year ago

Ok so the problem with the scrollTo methods is that the actual scroll position does not exist until it is rendered. You can keep scrolling until it reaches a point where it actually exists, but that's cumbersome.

Instead, I found a hacky way to the task:

list._config.overrideScrollPosition = () => list._itemPositions[itemIdx] 
list._renderChunk()
list._config.overrideScrollPosition = null
element.scrollTo(0, list._itemPositions[itemIdx])

The _renderChunk method relies on the scrollTop property, to avoid that, we override the scrolling computing function and then clear it out after rendering to reestablish normal behavior. Regarding the later scrollTo method, I cannot explain why it is necessary.

amnond commented 10 months ago

@lsmenicucci - thanks, that did the trick. In my case I have all the scroll positions in advance so there was no need to override the scrolling computing function. However, note that since

element.scrollTo(0, list._itemPositions[itemIdx])

moves the scrollbar to the y position where the item exists, the above will only work when there is one item per row. If there are more items per row, you should divide itemIdx by the number of items per row to get the correct y scroll position, i,e:

list._element.scrollTo(0, list._itemPositions[parseInt(itemIdx / items_per_row)])