infinity scroll in both directions

This commit is contained in:
Alexander Mahr 2025-02-15 18:49:48 +01:00
parent 52016afa57
commit c8dd0b22eb

View file

@ -10,6 +10,7 @@
box-sizing:border-box;
}
body,html{
background-color:#ffa;
margin:0;
padding:0
}
@ -17,27 +18,20 @@ padding:0
.infinityScroll{
height:50vh;
overflow:scroll;
border:1px solid red;
position:relative;
}
.space{
background:linear-gradient(white, blue);
height:300%;
opacity:0.5;
}
</style>
<style>
* {
font-family: sans;
}
/* disable pinch-zoom*/
:root {
touch-action: pan-x pan-y;
height: 100%
}
body{
background-color:#ffa;
margin:0
}
.monthview {
background-color:rgba(255,255,255,0.5);
border:2px solid rgba(0,0,0,0.5);
@ -48,6 +42,7 @@ body{
/* scroll-snap-align: center;*/
overflow:hidden;
}
.label{
background-color:#a44;
color:#fff;
@ -67,7 +62,10 @@ body{
align:content;
border:1px solid grey;
}
.weekend{
color:red;
background-color:white;
}
#mainDiv{
box-sizing:border-box;
@ -75,17 +73,12 @@ body{
/* scroll-snap-type: y mandatory;*/
height:100vh;
overflow:scroll;
border: 1px solid red;
margin:0;
width:100vw;
}
.orig{
border: 3px solid blue;
}
.weekend{
color:red;
background-color:white;
.orig{
box-shadow: 0 0 10px grey;
}
</style>
@ -93,26 +86,10 @@ border: 3px solid blue;
<div id="mainDiv" class="infinityScroll"></div>
<script>
// goals:
// 1. no/huge limits
// 1.1. scroll basis is a number (and hence scroll can continues as long as number can increase/descrease)
// 2. both directions
// 3. resetability
// answers
// todo: at center of scroll will be a div containing the number
// todo: onnce scrolling settled, the position reached is the new center
// questions
// Q1: what is to be scrolled ?
// A1: elements that are set to `.infinityScroll` class
// Q2: how is the scroll to infinity implemented (exponential stuff)
window.addEventListener("load",()=>{
var locale = window.navigator.userLanguage || window.navigator.language || "en";
function createMonthView(date = new Date()){
var monthviewDiv = document.createElement("div")
monthviewDiv.className = "monthview";
@ -123,11 +100,7 @@ window.addEventListener("load",()=>{
var daysDiv = document.createElement("div");
daysDiv.className="days";
monthviewDiv.appendChild(daysDiv);
// mainDiv.appendChild(monthviewDiv);
monthviewDiv.scrollIntoView();
// var weekendDiv = document.createElement("div");
// weekendDiv.className = "weekend";
// daysDiv.appendChild(weekendDiv);
var day = new Date(date);
day.setDate(1);
while(day.getMonth() == date.getMonth()){
@ -150,17 +123,6 @@ window.addEventListener("load",()=>{
function makeInfinityScroll(element){
element.nn=element.nn||{"position":0};
var mdate;
//var before = document.createElement("div");
//var after = document.createElement("div");
//after.style.backgroundColor="blue";
//var center = document.createElement("div");
//before.className = after.className = "space";
//after.style.background="linear-gradient(yellow,red)";
//center.textContent="center "+element.nn.position;
//center.style.border="1px solid red";
//center = createMonthView();
//center.nnindex=0;
//element.appendChild(after);
for(var i = -3; i< 3; i++){
mdate = new Date();
@ -174,56 +136,14 @@ window.addEventListener("load",()=>{
element.children[3].scrollIntoView({block:"center"});
setTimeout(()=>{
//console.log(element.firstChild,element.firstChild.nnindex);
var beforeind=0;
console.log("fc",element,element.firstChild);
if(element.firstChild.nnindex){
beforeind = element.firstChild.nnindex
}
mdate = new Date();
mdate.setMonth(mdate.getMonth()+beforeind-1);
var newBefore = createMonthView(mdate);
newBefore.nnindex=beforeind-1;
// newBefore.className="space";
console.log("prio "+element.scrollTop,""+element.scrollHeight,element.clientHeight);
// var savscrolltop = element.scrollTop;
element.insertBefore(newBefore,element.firstChild);
// element.scrollTop=savscrolltop-newBefore.clientHeight;
// var beforeind=0;
// console.log("fc",element,element.firstChild);
// if(element.firstChild.nnindex){
// beforeind = element.firstChild.nnindex
// }
// mdate = new Date();
// mdate.setMonth(mdate.getMonth()+beforeind-1);
// var newBefore = createMonthView(mdate);
// newBefore.nnindex=beforeind-1;
//// newBefore.className="space";
// console.log("prio "+element.scrollTop,""+element.scrollHeight,element.clientHeight);
// var savscrolltop = element.scrollTop;
// element.insertBefore(newBefore,element.firstChild);
// element.scrollTop=savscrolltop-newBefore.clientHeight;
//
// console.log("POST "+element.scrollTop,""+element.scrollHeight,element.clientHeight);
//
},100000);
element.addEventListener("scroll",()=>{
if(element.scrollUpdateSchedule!=1){
element.scrollUpdateSchedule=1;
requestAnimationFrame(()=>{
element.scrollUpdateSchedule=0;
//if(element.scrollTop/element.scrollHeight < 0.2){
// console.log("ch",element.clientHeight,element.scrollTop);
if(element.scrollTop < 3* element.clientHeight)
{
console.log(element.scrollTop)
//console.log(element.firstChild,element.firstChild.nnindex);
var beforeind=0;
if(element.firstChild.nnindex){
beforeind = element.firstChild.nnindex
@ -232,52 +152,37 @@ window.addEventListener("load",()=>{
mdate.setMonth(mdate.getMonth()+beforeind-1);
var newBefore = createMonthView(mdate);
newBefore.nnindex=beforeind-1;
// newBefore.className="space";
console.log("prio"+element.scrollTop,element.scrollHeight);
element.insertBefore(newBefore,element.firstChild);
console.log("POST"+element.scrollTop,element.scrollHeight);
// while(element.scrollHeight>200*element.clientHeight){
// element.children[element.children.length-1].remove();
// console.log("REMOVED"+element.scrollTop);
// }
while(element.scrollHeight>50*element.clientHeight){
element.lastChild.remove();
}
}
if(element.scrollTop > element.scrollHeight - 4* element.clientHeight)
{
var afterind=0;
if(element.lastChild.nnindex){
afterind = element.lastChild.nnindex
}
mdate = new Date();
mdate.setMonth(mdate.getMonth()+afterind+1);
var newAfter = createMonthView(mdate);
newAfter.nnindex=afterind+1;
element.appendChild(newAfter);
while(element.scrollHeight>50*element.clientHeight){
element.firstChild.remove();
}
}
});
}
},false);
}
/////-- if(element.scrollTop > element.scrollHeight - 4 * element.clientHeight)
/////-- {
/////-- //var afterind = element.children[element.children.length].nnindex || 0;
/////-- var afterind=0;
/////-- if(element.children[element.children.length-1].nnindex){
/////-- afterind = element.children[element.children.length-1].nnindex;
/////-- }
/////-- var newAfter = document.createElement("div");
/////--// newBefore.className="space";
/////-- newAfter.innerHTML=new Array(200).fill("a").map((a,i)=>{return afterind+"-"+i;}).join("<br>");
/////-- newAfter.nnindex=afterind+1;
/////-- console.log("prio"+element.scrollTop);
/////-- element.appendChild(newAfter);
/////-- console.log("POST"+element.scrollTop);
/////--
/////--
/////--// while(element.scrollHeight>200*element.clientHeight){
/////--// element.children[0].remove();
/////--// console.log("REMOVED"+element.scrollTop);
/////--// }
/////--
/////--
/////-- }
/////--// console.log(Date.now(),"Udpate",element.scrollTop);
/////-- console.log(Date.now(),"Udpate",element.scrollTop/element.scrollHeight,"AAA",element.scrollTop,">",element.scrollHeight - 4 * element.clientHeight,element.scrollHeight);
/////-- element.scrollUpdateSchedule=0;
/////-- });
/////-- }
// console.log(element.scrollTop);
// },false);
// }
document.querySelectorAll('.infinityScroll').forEach(makeInfinityScroll);