Infinite scroll
Bootstrap 5 Infinite scroll
This feature adds a scroll event listener, which is applied to either the window or the component it's
attached to (if the component has the overflow property set to scroll in the axis that matches the scroll
direction you're using). It calls a callback method each time a user reaches the end of a page or container.
Note: Read the API tab to find all available options and
advanced customization
Required ES init:
InfiniteScroll
*
*
UMD autoinits are enabled
by default. This means that you don't need to initialize
the component manually. However if you are using MDBootstrap ES format then you should pass
the required components to the initMDB
method.
Basic example
Scroll down the container below to add more items.
Note: Your element should be scrollable, for example, it should have
overflow-y: scroll
property like in the example below.
Direction
Use data-mdb-infinite-direction
to define the scrolling direction.
Angry
Dizzy
Flushed
Grimace
Grin
Spinners and asynchronous data
Window
You can apply the mdb.InfiniteScroll
instance to a window.
Note: You have to initialize an instance on your own, using JavaScript. If
you are using other containers, you have to make a check if your event.target
is
a window
.
import { InfiniteScroll, Ripple, LazyLoad, initMDB } from "mdb-ui-kit";
initMDB({ InfiniteScroll, Ripple, LazyLoad });
const postsContainer = document.getElementById('posts');
const spinner = document.getElementById('spinner');
const items = [
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/31.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/23.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/29.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/27.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/25.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/24.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/31.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/32.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
];
const getPostTemplate = (post) => {
return `
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init data-mdb-ripple-color="light">
<img src="${post.img}" class="w-100 lazy"/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);">
</div>
</a>
</div>
<h5>${post.title}</h5>
<p>${post.text}</p>
<a class="btn btn-info btn-rounded" href="#!" role="button">Read more</a>
</div>
`;
};
const posts = items.map((item) => getPostTemplate(item));
const generateRow = (firstPost, secondPost) => {
let el = document.createElement('div');
el.classList.add('row');
el.innerHTML = `
${firstPost}
${secondPost}
`;
return el;
};
const rows = [];
for (let i = 0; i < posts.length - 1; i += 2) {
rows.push(generateRow(posts[i], posts[i + 1]));
}
let renderedItems = 0;
const renderItems = (index) => {
setTimeout(() => {
spinner.style.display = 'none';
postsContainer.appendChild(rows[index]);
}, 1500);
};
const loadItems = () => {
if (renderedItems < rows.length) {
postsContainer.appendChild(spinner);
spinner.style.display = 'flex';
renderItems(renderedItems);
renderedItems++;
if (renderedItems === rows.length) {
window.removeEventListener('completed.mdb.infiniteScroll', loadItems);
}
}
};
window.addEventListener('completed.mdb.infiniteScroll', loadItems);
new InfiniteScroll(window);
const postsContainer = document.getElementById('posts');
const spinner = document.getElementById('spinner');
const items = [
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/31.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/23.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/29.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/27.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/25.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/24.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/31.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
{
img: 'https://mdbcdn.b-cdn.net/img/Photos/Others/images/32.webp',
title: 'This is an title of the article',
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam cupiditate veniam voluptatibus laudantium cum dolorem illo. Quos architecto deserunt saepe.',
},
];
const getPostTemplate = (post) => {
return `
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init data-mdb-ripple-color="light">
<img src="${post.img}" class="w-100 lazy"/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);">
</div>
</a>
</div>
<h5>${post.title}</h5>
<p>${post.text}</p>
<a class="btn btn-info btn-rounded" href="#!" role="button">Read more</a>
</div>
`;
};
const posts = items.map((item) => getPostTemplate(item));
const generateRow = (firstPost, secondPost) => {
let el = document.createElement('div');
el.classList.add('row');
el.innerHTML = `
${firstPost}
${secondPost}
`;
return el;
};
const rows = [];
for (let i = 0; i < posts.length - 1; i += 2) {
rows.push(generateRow(posts[i], posts[i + 1]));
}
let renderedItems = 0;
const renderItems = (index) => {
setTimeout(() => {
spinner.style.display = 'none';
postsContainer.appendChild(rows[index]);
}, 1500);
};
const loadItems = () => {
if (renderedItems < rows.length) {
postsContainer.appendChild(spinner);
spinner.style.display = 'flex';
renderItems(renderedItems);
renderedItems++;
if (renderedItems === rows.length) {
window.removeEventListener('completed.mdb.infiniteScroll', loadItems);
}
}
};
window.addEventListener('completed.mdb.infiniteScroll', loadItems);
new mdb.InfiniteScroll(window);