ui/utilities/VirtualScroll.min.js

2 lines
1.8 KiB
JavaScript
Raw Normal View History

const VirtualScroll=(t={})=>{const e=new Map,l=new Map;let i=1;const n=globalThis.Util.newAvg();let o=0,a=0,r=0,s=null,c=null,h=!1;const g=t.itemHeight||null;return{reset:(t,u)=>{if(h=!1,e.clear(),l.clear(),n.clear(),r=0,s=null,c=null,!t?.length)return[];const f=t.length;i=Math.ceil(Math.sqrt(f))||10;const m=window.getComputedStyle(u);o=parseFloat(m.paddingTop)||0,a=parseFloat(m.rowGap)||0;const p=Math.max(10,Math.ceil((u.clientHeight||100)/(g||32)));return t.slice(0,Math.min(3*p,f))},init:(t,o)=>{if(h)return;const a=t.length;let r=g||n.get()||32;a>0&&"object"==typeof t[0]&&null!==t[0]&&t[0]._itemHeight&&(r=t[0]._itemHeight),n.add(r),null===s&&(s=0,c=0);for(let l=0;l<a;l++)if(!e.has(l)){const i="object"==typeof t[l]&&null!==t[l]&&t[l]._itemHeight?t[l]._itemHeight:r;e.set(l,i)}for(let t=0;t<a;t+=i)l.set(t,Math.min(i,a-t)*r);h=!0,o()},update:(t,o)=>{if(0===o.offsetHeight)return;if(null===s){const t=window.getComputedStyle(o);s=parseFloat(t.marginTop)||0,c=parseFloat(t.marginBottom)||0}0!==t||r||(r=s);const h=o.offsetHeight+s+c+a,g=e.get(t);if(h!==g){e.set(t,h),n.add(h);const o=h-(g||0),a=t-t%i;l.has(a)&&l.set(a,l.get(a)+o)}},calc:(t,s)=>{if(!h||!s)return null;const c=s.length,g=Math.max(16,n.get()||32);let u=Math.max(10,Math.ceil((t.clientHeight||100)/g)),f=o+r+a,m=0,p=0,M=0,d=0,H=[];const w=t.scrollTop;let x=0;for(let t=0;t<c;t++){if(++x>2*c)throw new Error("VirtualScroll infinite loop");if(0===p){const n=l.get(t);if(n&&f+n<=w&&t+i<c)f+=n,t+=i-1;else{const l=e.get(t);if(f+l<=w&&t<c-1)f+=l;else{p=1;let l=Math.max(0,t);M=Math.max(0,l-u),d=Math.min(M+3*u,c),t=d-1,H=s.slice(M,d);for(let t=M;t<l;t++)f-=e.get(t)}}}else if(1===p){const n=l.get(t);n?(m+=n,t+=i-1):m+=e.get(t)}}return{prevHeight:Math.max(0,f-o-r-a-(M>0?a:0)),postHeight:m>0?Math.max(0,m-2*a):0,renderedList:H,listStartIndex:M}}}};globalThis.VirtualScroll=VirtualScroll;