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; box-sizing:border-box;
} }
body,html{ body,html{
background-color:#ffa;
margin:0; margin:0;
padding:0 padding:0
} }
@ -17,27 +18,20 @@ padding:0
.infinityScroll{ .infinityScroll{
height:50vh; height:50vh;
overflow:scroll; overflow:scroll;
border:1px solid red;
position:relative; position:relative;
} }
.space{
background:linear-gradient(white, blue);
height:300%;
opacity:0.5;
}
</style>
<style>
* { * {
font-family: sans; font-family: sans;
} }
/* disable pinch-zoom*/
:root { :root {
touch-action: pan-x pan-y; touch-action: pan-x pan-y;
height: 100% height: 100%
} }
body{
background-color:#ffa;
margin:0
}
.monthview { .monthview {
background-color:rgba(255,255,255,0.5); background-color:rgba(255,255,255,0.5);
border:2px solid rgba(0,0,0,0.5); border:2px solid rgba(0,0,0,0.5);
@ -48,6 +42,7 @@ body{
/* scroll-snap-align: center;*/ /* scroll-snap-align: center;*/
overflow:hidden; overflow:hidden;
} }
.label{ .label{
background-color:#a44; background-color:#a44;
color:#fff; color:#fff;
@ -67,7 +62,10 @@ body{
align:content; align:content;
border:1px solid grey; border:1px solid grey;
} }
.weekend{
color:red;
background-color:white;
}
#mainDiv{ #mainDiv{
box-sizing:border-box; box-sizing:border-box;
@ -75,17 +73,12 @@ body{
/* scroll-snap-type: y mandatory;*/ /* scroll-snap-type: y mandatory;*/
height:100vh; height:100vh;
overflow:scroll; overflow:scroll;
border: 1px solid red;
margin:0; margin:0;
width:100vw; width:100vw;
} }
.orig{
border: 3px solid blue; .orig{
} box-shadow: 0 0 10px grey;
.weekend{
color:red;
background-color:white;
} }
</style> </style>
@ -93,26 +86,10 @@ border: 3px solid blue;
<div id="mainDiv" class="infinityScroll"></div> <div id="mainDiv" class="infinityScroll"></div>
<script> <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",()=>{ window.addEventListener("load",()=>{
var locale = window.navigator.userLanguage || window.navigator.language || "en"; var locale = window.navigator.userLanguage || window.navigator.language || "en";
function createMonthView(date = new Date()){ function createMonthView(date = new Date()){
var monthviewDiv = document.createElement("div") var monthviewDiv = document.createElement("div")
monthviewDiv.className = "monthview"; monthviewDiv.className = "monthview";
@ -123,11 +100,7 @@ window.addEventListener("load",()=>{
var daysDiv = document.createElement("div"); var daysDiv = document.createElement("div");
daysDiv.className="days"; daysDiv.className="days";
monthviewDiv.appendChild(daysDiv); monthviewDiv.appendChild(daysDiv);
// mainDiv.appendChild(monthviewDiv);
monthviewDiv.scrollIntoView(); monthviewDiv.scrollIntoView();
// var weekendDiv = document.createElement("div");
// weekendDiv.className = "weekend";
// daysDiv.appendChild(weekendDiv);
var day = new Date(date); var day = new Date(date);
day.setDate(1); day.setDate(1);
while(day.getMonth() == date.getMonth()){ while(day.getMonth() == date.getMonth()){
@ -150,17 +123,6 @@ window.addEventListener("load",()=>{
function makeInfinityScroll(element){ function makeInfinityScroll(element){
element.nn=element.nn||{"position":0}; element.nn=element.nn||{"position":0};
var mdate; 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++){ for(var i = -3; i< 3; i++){
mdate = new Date(); mdate = new Date();
@ -174,56 +136,14 @@ window.addEventListener("load",()=>{
element.children[3].scrollIntoView({block:"center"}); 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",()=>{ element.addEventListener("scroll",()=>{
if(element.scrollUpdateSchedule!=1){ if(element.scrollUpdateSchedule!=1){
element.scrollUpdateSchedule=1; element.scrollUpdateSchedule=1;
requestAnimationFrame(()=>{ requestAnimationFrame(()=>{
element.scrollUpdateSchedule=0; element.scrollUpdateSchedule=0;
//if(element.scrollTop/element.scrollHeight < 0.2){
// console.log("ch",element.clientHeight,element.scrollTop);
if(element.scrollTop < 3* element.clientHeight) if(element.scrollTop < 3* element.clientHeight)
{ {
console.log(element.scrollTop)
//console.log(element.firstChild,element.firstChild.nnindex);
var beforeind=0; var beforeind=0;
if(element.firstChild.nnindex){ if(element.firstChild.nnindex){
beforeind = element.firstChild.nnindex beforeind = element.firstChild.nnindex
@ -232,52 +152,37 @@ window.addEventListener("load",()=>{
mdate.setMonth(mdate.getMonth()+beforeind-1); mdate.setMonth(mdate.getMonth()+beforeind-1);
var newBefore = createMonthView(mdate); var newBefore = createMonthView(mdate);
newBefore.nnindex=beforeind-1; newBefore.nnindex=beforeind-1;
// newBefore.className="space";
console.log("prio"+element.scrollTop,element.scrollHeight);
element.insertBefore(newBefore,element.firstChild); element.insertBefore(newBefore,element.firstChild);
console.log("POST"+element.scrollTop,element.scrollHeight);
// while(element.scrollHeight>200*element.clientHeight){ while(element.scrollHeight>50*element.clientHeight){
// element.children[element.children.length-1].remove(); element.lastChild.remove();
// console.log("REMOVED"+element.scrollTop); }
// }
} }
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); },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); document.querySelectorAll('.infinityScroll').forEach(makeInfinityScroll);