const N = 12; class ProgView { constructor(addfn) { this.n = null; this.s = null; this.last = 0; this.stored = false; this.first = true; this.loading = false; this.nomore = false; this.addelements = addfn; this.load(); this.down(this.n).then(() => { let app = this; (function ev() { if (document.documentElement.scrollHeight < app.s) { setTimeout(ev, 50); } else { window.scrollTo(0, app.s); } })(); }); } get n() { return this.nval; } set n(sn) { this.nval = sn == null ? N : Number(sn); } get s() { return this.sval; } set s(ss) { this.sval = ss == null ? 0 : Number(ss); } arm() { window.onscroll = (ev) => { if ((window.innerHeight + window.scrollY + 50) >= document.body.offsetHeight) { this.down(); } }; } disarm() { window.onscroll = null; } store(s) { this.stored = true; this.n = this.last; this.s = window.scrollY; sessionStorage.setItem("n", this.n); sessionStorage.setItem("s", this.s); } load() { this.n = window.sessionStorage.getItem("n"); this.s = window.sessionStorage.getItem("s"); } clear() { sessionStorage.removeItem("n"); sessionStorage.removeItem("s"); } stopload() { let gif = document.querySelector("div#load > img"); gif.remove(); } startload() { let load = document.getElementById("load"); let gif = document.createElement("img"); gif.setAttribute("src", "static/load.gif"); gif.setAttribute("class", "load"); load.appendChild(gif); return true; } async down(n) { n = n == null ? this.n : n; this.disarm(); if (!this.loading && !this.nomore) { this.loading = true; this.startload(); await fetch(`list?o=${this.last}&n=${n}`) .then(response => { if (!response.ok) { throw `down(): error ${response.status}`; } else { return response.json(); } }) .then(data => { this.nomore = this.addelements(data, this.s); }) .catch(error => { console.error(error); }) .finally(() => { this.stopload(); this.arm(); this.loading = false; }); this.last += n; } } addelements() { return true; } }