Instead of listening to the scroll event you should have a look at Intersection Observer (IO) With IO you can react to when an element comes into view (or is about to come into view) / leaves the view. Smashing Magazine also has a great article about it, great pictures to help you understand it.
You could do it at follows for your your problem: You add an observable div at the end of your Content and whenever this div is about to get into view you load more data to append to the div.
Here is a tutorial on how you can do this. Keep in mind you don't have to show the "loading" text like in the example, that's just so you see what's going on.
It boils down to the following:
First you define the options for your IO:
let options = {
rootMargin: '50px'
}
let observer = new IntersectionObserver(callback, options);
Then you must define which element you want to watch for intersections:
let entries = document.querySelectorAll('.load-more-content'); // example for observing more elements, you can also observe just one.
entries.forEach(entry => {observer.observe(entry);}) // if you observe one, you don't need the forEach part.
Last you need to define the callback function, what should happen once the observed element comes into view:
const observer = new IntersectionObserver(function (entries, self) {
entries.forEach(entry => {
if (entry.isIntersecting) {
// load more content
}
});
}, config);
An easy example, whenever you scroll to the bottom of the content div, another div is appended. There is no ajax involved in this example, you might want to unobserve the IO once you don't have any more data to append from your ajax call.
Support is good for all major browsers, if you need to support IE there is a polyfill from w3c you can use.
const loadMore = document.querySelector('.load-more-content');
const config = {
rootMargin: '50px',
threshold: [.2, .9]
};
const observer = new IntersectionObserver(function (entries, self) {
entries.forEach(entry => {
if (entry.isIntersecting) {
var content = document.querySelector('.my-content');
content.innerHTML = content.innerHTML + '<div class="my-content"> More was "loaded"</div>';
}
});
}, config);
observer.observe(loadMore);
header,
footer {
height: 10vh;
background: pink;
}
.wrapper {
height: 80vh;
overflow: auto;
}
.my-content {
min-height: 150vh;
}
<header> Some content </header>
<div class="wrapper">
<div class="my-content">
<p> Lorem Ipsum </p>
</div>
<div class="load-more-content">
<!-- Whenever this div comes into view, we load more -->
</div>
</div>
<footer>Content </footer>