Reputation: 4988
I am trying to get new data when reaching the end of the content of a div element with overflow: scroll
I have searched for an example of this but to with no success. I have researched on MDN and found the wheel event, in the event I found the LayerY property
The method I thought might work is as follows. When scrolling down and if the value of the LayerY
property is repeated n
times, it is at the end of the content, so I make the call to the resource.
For example
let repeat = 0;
let value = 0;
const div = document.querySelector('div');
div.addEventListener('wheel', wheelHandler);
function wheelHandler(event) {
if (value > 150 && value === event.layerY) {
repeat += 1;
}
if (value > 150 && repeat > 3) {
console.log('fetch data');
repeat = 0; // set repeat to 0 after fetch data
}
value = event.layerY;
}
* {
box-sizing: border-box;
}
div {
width: 500px;
height: 200px;
border: 1px solid gray;
overflow: scroll;
padding: 10px;
}
<div>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed exercitationem
doloribus cum, atque quibusdam nemo dolorem, quia omnis, libero consequatur
molestiae error facilis maxime pariatur delectus aliquam sunt porro vel.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed exercitationem
doloribus cum, atque quibusdam nemo dolorem, quia omnis, libero consequatur
molestiae error facilis maxime pariatur delectus aliquam sunt porro vel.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed exercitationem
doloribus cum, atque quibusdam nemo dolorem, quia omnis, libero consequatur
molestiae error facilis maxime pariatur delectus aliquam sunt porro vel.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed exercitationem
doloribus cum, atque quibusdam nemo dolorem, quia omnis, libero consequatur
molestiae error facilis maxime pariatur delectus aliquam sunt porro vel.
</div>
There are other scenarios, for example handle if you scroll up
Is there a native way to achieve the expected result? either is this path correct
I appreciate your advice and ideas
Upvotes: 0
Views: 247
Reputation: 1119
actually i have spent a bit more time and explained it a bit more but if you spent some time reading it will be useful to understand everything
so i have created a little widget that's shows current details and also i have attached a diagram to clear things visually
const main = document.querySelector(".items")
const vals = document.querySelectorAll(".vals")
main.onscroll = e => {
let st = main.scrollTop,
sh = main.scrollHeight,
ch = main.clientHeight,
scrollEnded = st + ch >= sh
vals[0].innerHTML = st
vals[1].innerHTML = sh
vals[2].innerHTML = ch
vals[3].innerHTML = st + ch
vals[4].innerHTML = scrollEnded ? `<div class="bg-green-500 p-1 px-2 rounded-md text-white">end</div>`:`<div class="bg-red-500 p-1 px-2 rounded-md text-white">not-end</div>`
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet"/>
<div class="root flex justify-start">
<!-- main scroll element -->
<div class="items p-5 border bg-gray-50 w-64 h-36 overflow-y-scroll">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste dolorem doloribus consequatur modi eius necessitatibus. Doloremque, eligendi rerum consequuntur delectus quisquam voluptatum harum, architecto eveniet commodi fugiat aliquid nemo iste?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste dolorem doloribus consequatur modi eius necessitatibus. Doloremque, eligendi rerum consequuntur delectus quisquam voluptatum harum, architecto eveniet commodi fugiat aliquid nemo iste?
</div>
<!-- extra demo thing -->
<div class="details p-2 text-sm font-normal top-0 w-[400px] bg-gray-100">
<div class="each-values flex">
<div class="mr-2">scroll-top</div>
<div class="vals"></div>
</div>
<div class="each-values flex">
<div class="mr-2">scroll-height</div>
<div class="vals"></div>
</div>
<div class="each-values flex">
<div class="mr-2">client-height</div>
<div class="vals"></div>
</div>
<div class="each-values flex">
<div class="mr-2">scroll-top + client-height</div>
<div class="vals"></div>
</div>
<div class="each-values flex">
<div class="mr-2">scroll-top + client-height >= scroll-height</div>
<div class="vals"></div>
</div>
</div>
</div>
here i have made a class function to sum up all the work in one function updated : (when reaching bottom event can be triggered multiple times to avoid this the class function is also tracking last trigger point)
class scroll_bottom {
constructor(el,obe){
const obj = this
this.el = el
this.lastPoint = 0;
this.onBottomEvent = obe
function forScroll(){
let st = obj.el.scrollTop,
sh = obj.el.scrollHeight,
ch = obj.el.clientHeight,
sp = st + ch,
scrollEnded = sp >= sh
if(scrollEnded){
if(this.lastPoint != sp){obj.onBottomEvent(sp)}
this.lastPoint = sp
}
}
this.el.onscroll = forScroll
}
}
// example use
const main = document.querySelector(".items")
let index = 1
new scroll_bottom(main,function(e){
// #code for scroll bottom here
main.innerHTML += `Lorem ipsum dolor sit amet consectetur adipisicing elit. Quas qui totam vel, et iste autem unde distinctio iure non. Suscipit autem, officiis dolorem eaque rerum quia facere voluptates repudiandae laudantium!`
console.log("changed " + index +" time" + (index > 1 ? "s" : ""))
index++
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet"/>
<!-- main scroll element -->
<div class="items mt-5 p-5 border bg-gray-50 w-64 h-36 overflow-y-scroll">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste dolorem doloribus consequatur modi eius necessitatibus. Doloremque, eligendi rerum consequuntur delectus quisquam voluptatum harum, architecto eveniet commodi fugiat aliquid nemo iste?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste dolorem doloribus consequatur modi eius necessitatibus. Doloremque, eligendi rerum consequuntur delectus quisquam voluptatum harum, architecto eveniet commodi fugiat aliquid nemo iste?
</div>
Upvotes: 2