fix and optimize infinate scroller

This commit is contained in:
MathMan05 2024-08-17 22:03:29 -05:00
parent 80533daef1
commit 9bf6da8592
2 changed files with 48 additions and 15 deletions

View file

@ -14,7 +14,7 @@ class InfiniteScroller {
this.destroyFromID = destroyFromID; this.destroyFromID = destroyFromID;
this.reachesBottom = reachesBottom; this.reachesBottom = reachesBottom;
} }
interval; timeout;
async getDiv(initialId, bottom = true) { async getDiv(initialId, bottom = true) {
const div = document.createElement("div"); const div = document.createElement("div");
div.classList.add("messagecontainer"); div.classList.add("messagecontainer");
@ -23,8 +23,9 @@ class InfiniteScroller {
scroll.classList.add("flexttb", "scroller"); scroll.classList.add("flexttb", "scroller");
div.appendChild(scroll); div.appendChild(scroll);
this.div = div; this.div = div;
this.interval = setInterval(this.updatestuff.bind(this), 100); //this.interval=setInterval(this.updatestuff.bind(this,true),100);
this.scroll = scroll; this.scroll = scroll;
this.div.addEventListener("scroll", this.watchForChange.bind(this));
this.scroll.addEventListener("scroll", this.watchForChange.bind(this)); this.scroll.addEventListener("scroll", this.watchForChange.bind(this));
{ {
let oldheight = 0; let oldheight = 0;
@ -47,12 +48,20 @@ class InfiniteScroller {
} }
scrollBottom; scrollBottom;
scrollTop; scrollTop;
updatestuff() { needsupdate = true;
async updatestuff() {
this.timeout = null;
this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight; this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight;
this.scrollTop = this.scroll.scrollTop; this.scrollTop = this.scroll.scrollTop;
if (!this.scrollBottom) { if (!this.scrollBottom) {
if (!await this.watchForChange()) {
this.reachesBottom(); this.reachesBottom();
} }
}
if (!this.scrollTop) {
await this.watchForChange();
}
this.needsupdate = false;
//this.watchForChange(); //this.watchForChange();
} }
async firstElement(id) { async firstElement(id) {
@ -109,6 +118,7 @@ class InfiniteScroller {
if (again) { if (again) {
await this.watchForTop(); await this.watchForTop();
} }
return again;
} }
async watchForBottom() { async watchForBottom() {
let again = false; let again = false;
@ -139,6 +149,7 @@ class InfiniteScroller {
if (again) { if (again) {
await this.watchForBottom(); await this.watchForBottom();
} }
return again;
} }
async watchForChange() { async watchForChange() {
try { try {
@ -152,11 +163,16 @@ class InfiniteScroller {
this.currrunning = false; this.currrunning = false;
return; return;
} }
await Promise.allSettled([this.watchForTop(), this.watchForBottom()]); const out = await Promise.allSettled([this.watchForTop(), this.watchForBottom()]);
const changed = (out[0] || out[1]);
if (null === this.timeout && changed) {
this.timeout = setTimeout(this.updatestuff.bind(this), 300);
}
if (!this.currrunning) { if (!this.currrunning) {
console.error("something really bad happened"); console.error("something really bad happened");
} }
this.currrunning = false; this.currrunning = false;
return !!changed;
} }
catch (e) { catch (e) {
console.error(e); console.error(e);
@ -201,7 +217,7 @@ class InfiniteScroller {
await this.destroyFromID(thing[1]); await this.destroyFromID(thing[1]);
} }
this.HTMLElements = []; this.HTMLElements = [];
clearInterval(this.interval); clearInterval(this.timeout);
if (this.div) { if (this.div) {
this.div.remove(); this.div.remove();
} }

View file

@ -14,7 +14,7 @@ class InfiniteScroller{
this.destroyFromID=destroyFromID; this.destroyFromID=destroyFromID;
this.reachesBottom=reachesBottom; this.reachesBottom=reachesBottom;
} }
interval:NodeJS.Timeout; timeout:NodeJS.Timeout;
async getDiv(initialId:string,bottom=true):Promise<HTMLDivElement>{ async getDiv(initialId:string,bottom=true):Promise<HTMLDivElement>{
const div=document.createElement("div"); const div=document.createElement("div");
div.classList.add("messagecontainer"); div.classList.add("messagecontainer");
@ -23,9 +23,10 @@ class InfiniteScroller{
scroll.classList.add("flexttb","scroller") scroll.classList.add("flexttb","scroller")
div.appendChild(scroll); div.appendChild(scroll);
this.div=div; this.div=div;
this.interval=setInterval(this.updatestuff.bind(this),100); //this.interval=setInterval(this.updatestuff.bind(this,true),100);
this.scroll=scroll; this.scroll=scroll;
this.div.addEventListener("scroll",this.watchForChange.bind(this));
this.scroll.addEventListener("scroll",this.watchForChange.bind(this)); this.scroll.addEventListener("scroll",this.watchForChange.bind(this));
{ {
let oldheight=0; let oldheight=0;
@ -49,12 +50,20 @@ class InfiniteScroller{
} }
scrollBottom:number; scrollBottom:number;
scrollTop:number; scrollTop:number;
updatestuff(){ needsupdate=true;
async updatestuff(){
this.timeout=null;
this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight; this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight;
this.scrollTop=this.scroll.scrollTop; this.scrollTop=this.scroll.scrollTop;
if(!this.scrollBottom){ if(!this.scrollBottom){
if(!await this.watchForChange()){
this.reachesBottom(); this.reachesBottom();
} }
}
if(!this.scrollTop){
await this.watchForChange()
}
this.needsupdate=false;
//this.watchForChange(); //this.watchForChange();
} }
async firstElement(id:string){ async firstElement(id:string){
@ -77,7 +86,7 @@ class InfiniteScroller{
} }
} }
} }
private async watchForTop():Promise<void>{ private async watchForTop():Promise<boolean>{
let again=false; let again=false;
if(this.scrollTop===0){ if(this.scrollTop===0){
this.scrollTop=1; this.scrollTop=1;
@ -111,8 +120,9 @@ class InfiniteScroller{
if(again){ if(again){
await this.watchForTop(); await this.watchForTop();
} }
return again;
} }
async watchForBottom():Promise<void>{ async watchForBottom():Promise<boolean>{
let again=false; let again=false;
const scrollBottom = this.scrollBottom; const scrollBottom = this.scrollBottom;
if(scrollBottom<this.minDist){ if(scrollBottom<this.minDist){
@ -142,8 +152,10 @@ class InfiniteScroller{
if(again){ if(again){
await this.watchForBottom(); await this.watchForBottom();
} }
return again;
} }
async watchForChange():Promise<void>{ async watchForChange():Promise<boolean>{
try{ try{
if(this.currrunning){ if(this.currrunning){
return; return;
@ -151,9 +163,14 @@ class InfiniteScroller{
this.currrunning=true; this.currrunning=true;
} }
if(!this.div){this.currrunning=false;return} if(!this.div){this.currrunning=false;return}
await Promise.allSettled([this.watchForTop(),this.watchForBottom()]) const out=await Promise.allSettled([this.watchForTop(),this.watchForBottom()])
const changed=(out[0]||out[1]);
if(null===this.timeout&&changed){
this.timeout=setTimeout(this.updatestuff.bind(this),300);
}
if(!this.currrunning){console.error("something really bad happened")} if(!this.currrunning){console.error("something really bad happened")}
this.currrunning=false; this.currrunning=false;
return !!changed;
}catch(e){ }catch(e){
console.error(e); console.error(e);
} }
@ -196,7 +213,7 @@ class InfiniteScroller{
await this.destroyFromID(thing[1]); await this.destroyFromID(thing[1]);
} }
this.HTMLElements=[]; this.HTMLElements=[];
clearInterval(this.interval); clearInterval(this.timeout);
if(this.div){ if(this.div){
this.div.remove(); this.div.remove();
} }