dataTable/src/scroll.js

53 lines
1.9 KiB
JavaScript
Raw Normal View History

import { VirtualScroll } from '@web/base';
export const createScrollManager = (container, state, onRenderedListChange) => {
const vs = VirtualScroll();
let scrollEl = null;
const refresh = () => {
if (!scrollEl) return;
const virtualContainer = {
clientHeight: scrollEl.clientHeight * 1.6,
scrollTop: scrollEl.scrollTop
};
const res = vs.calc(virtualContainer, state.list);
if (res) {
Object.assign(state, {
prevHeight: res.prevHeight,
postHeight: res.postHeight,
_listStartIndex: res.listStartIndex,
_renderedList: res.renderedList
});
onRenderedListChange?.(res.renderedList.length);
}
};
return {
init: () => {
scrollEl = container.querySelector('.dt-main');
},
reset: (list) => {
state._listStartIndex = 0;
state._renderedList = vs.reset(list, scrollEl || container) || [];
// Performance Fix: Seed the VirtualScroll average height to 40px BEFORE init().
// This entirely eliminates the need for onItemUpdate (which causes layout thrashing
// during fast scrolls) while still perfectly fixing the "row 70 jump" bug caused
// by VirtualScroll's 32px default assumption.
const mockNode = document.createElement('div');
mockNode.style.marginTop = '0px';
mockNode.style.marginBottom = '0px';
Object.defineProperty(mockNode, 'offsetHeight', { value: 40 });
document.body.appendChild(mockNode);
vs.update(0, mockNode);
document.body.removeChild(mockNode);
if (state.list === list) {
vs.init(list, refresh);
}
},
refresh,
onScroll: refresh
};
};