I want to avoid using jQuery or another library for the sake of keeping my code minimal, I need very little in the way of features, I just want to append to a list when the user scrolls to the bottom. How would I do this in plain Javascript?
Basicaly you just need to hook the event scroll, check if the user scrolled down enough and add some content if so:
<html><body>
<div id="test">scroll to understand</div>
<div id="wrapper" style="height: 400px; overflow: auto;">
<div id="content"> </div>
</div>
<script language="JavaScript">
// we will add this content, replace for anything you want to add
var more = '<div style="height: 1000px; background: #EEE;"></div>';
var wrapper = document.getElementById("wrapper");
var content = document.getElementById("content");
var test = document.getElementById("test");
content.innerHTML = more;
// cross browser addEvent, today you can safely use just addEventListener
function addEvent(obj,ev,fn) {
if(obj.addEventListener) obj.addEventListener(ev,fn,false);
else if(obj.attachEvent) obj.attachEvent("on"+ev,fn);
}
// this is the scroll event handler
function scroller() {
// print relevant scroll info
test.innerHTML = wrapper.scrollTop+"+"+wrapper.offsetHeight+"+100>"+content.offsetHeight;
// add more contents if user scrolled down enough
if(wrapper.scrollTop+wrapper.offsetHeight+100>content.offsetHeight) {
content.innerHTML+= more;
}
}
// hook the scroll handler to scroll event
addEvent(wrapper,"scroll",scroller);
</script>
</body></html>
For achieving this behaviour you don't need jQuery or a jQuery plugin. You can use only CSS or JavaScript (if you want to cover all browsers).
But don't use onScroll
: you can do all of this with just vanilla JS and the Intersection Observer API.
All you need to do is place elements and listen for when they become available in the screen. The Intersection Observer API is very customisable to fit all your needs.
In summary: you accomplish that with a few JavaScript & HTML lines and it's much more performant than listening for scroll events in the browser.
Excellent demo code for infinite scroll. Goes to show that you don't need jQuery and Angular for any browser independent work. But new boys today are out of touch with pure Javascript that we old guys still trust and use. Here I have simplified the code further:
// we will add this content, replace for anything you want to add
var wrapper, content, test;
var more = '<div style="height:1000px; background:#EEE;"></div>';
// this is the scroll event handler
function scroller() {
// print relevant scroll info
test.innerHTML = wrapper.scrollTop + " + " + wrapper.offsetHeight + " + 100 > " + content.offsetHeight;
// add more contents if user scrolled down enough
if (wrapper.scrollTop + wrapper.offsetHeight + 100 > content.offsetHeight) {
content.innerHTML += more; // NK: Here you can make an Ajax call and fetch content to append to content.innerHTML
}
}
wrapper = document.getElementById("wrapper");
content = document.getElementById("content");
test = document.getElementById("test");
content.innerHTML = more;
// hook the scroll handler to scroll event
if (wrapper.addEventListener) // NK: Works on all new browsers
wrapper.addEventListener("scroll", scroller, false);
else if (wrapper.attachEvent) // NK: Works on old IE
wrapper.attachEvent("onscroll", scroller);
<div id="test">scroll to understand</div>
<div id="wrapper" style="height: 400px; overflow: auto;">
<div id="content"> </div>
</div>
domElem.addEventListener(
'scroll',
function(evt) { ... },
false
);
and handle evt/scroll position appropriately.
I see great answers to your question, but for a scrolling that is not associated with any HTML element or content (just an empty HTML page), here is how I did it:
document.querySelector("body").style.height = "1000px";
window.addEventListener("scroll", function() {
var body = document.querySelector("body");
var height = body.style.height;
height = height.slice(0, -2);
height = Number(height);
return function() {
if(height - window.scrollY < 700) {
height += height / 2;
}
body.style.height = height + "px";
};
}());
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>
I hope this helps someone out there :)
Actually a simplified version of @Jan Turon's version worked for me:
<html>
<head>
<title>Infinite scroll</title>
<style>
body {
font: Arial, san-serif;
background-color: rgb(130, 75, 8);
color: black;
}
</style>
</head>
<body>
<div id="test">scroll to understand</div>
<div id="wrapper" style="height: 400px; overflow: auto;">
<div id="content"> </div>
</div>
</body>
<script>
var more = '<div style="height: 1000px; background: #EEE;">This is content</div>';
var test = document.getElementById("test");
var wrapper = document.getElementById("wrapper");
var content = document.getElementById("content");
content.innerHTML = more;
const scrollHandler = () => {
// test.innerHTML = wrapper.scrollTop + " + " + wrapper.offsetHeight + " + 100 > " + content.offsetHeight;
if (wrapper.scrollTop + wrapper.offsetHeight + 100 > content.offsetHeight) {
content.innerHTML += more;
}
}
wrapper.addEventListener("scroll", scrollHandler);
</script>
</html>
Assume HTML:
<div class="container"></div>
let container = document.querySelector('.container');
// when user scrolls to last list item in view, wait for 1.5seconds and load next 10 list items, and continue thus.
window.addEventListener('scroll', function(){
setTimeout(() => {
loadMoreList(5);
}, 1500);
});
loadMoreList(20); // load first 20 list items.
function loadMoreList(num) {
let scrollY = window.scrollY;
let innerHeight = window.innerHeight;
let offsetHeight = document.body.offsetHeight;
if (scrollY + innerHeight > offsetHeight - 100) {
let item = 1;
let ul = document.createElement('ul');
for (var i = 0; i < num; i++) {
let li = document.createElement('li');
li.innerText = 'List Item ' + item++;
ul.appendChild(li);
container.appendChild(ul);
}
}
}
Note: The more important parts are: the scroll event listener and the loadMoreList function. You don't necessarily need the argument num.
The for loop just ensures that on load, the function is called and 20 items are uniquely created and displayed.
© 2022 - 2024 — McMap. All rights reserved.