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
*
*
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.
- Angry
- Dizzy
- Flushed
- Frown
- Grimace
- Grin
<ul
class="container list-group infinite-scroll-basic"
id="basic-example"
data-mdb-infinite-scroll-init
style="max-height: 261px; overflow-y: scroll"
>
<li class="list-group-item d-flex align-items-center">
<i class="far fa-angry fa-3x me-4"></i> Angry
</li>
<li class="list-group-item d-flex align-items-center">
<i class="far fa-dizzy fa-3x me-4"></i> Dizzy
</li>
<li class="list-group-item d-flex align-items-center">
<i class="far fa-flushed fa-3x me-4"></i> Flushed
</li>
<li class="list-group-item d-flex align-items-center">
<i class="far fa-frown fa-3x me-4"></i> Frown
</li>
<li class="list-group-item d-flex align-items-center">
<i class="far fa-grimace fa-3x me-4"></i> Grimace
</li>
<li class="list-group-item d-flex align-items-center">
<i class="far fa-grin fa-3x me-4"></i> Grin
</li>
</ul>
import { InfiniteScroll, initMDB } from "mdb-ui-kit";
initMDB({ InfiniteScroll });
// An array of icon names
const icons = [
'Sad-Tear',
'Meh-Blank',
'Smile-Wink',
'Tired',
'Surprise',
'Kiss-Beam',
'Laugh-Squint',
];
// Get a scrollable container using an id attribute
const basicElement = document.getElementById('basic-example');
// An index of elements added after scrolling to the end of the container
let itemIndex = 0;
// items - an array of the created elements using the loop through icons array
const items = icons.map((icon) => {
// Create a list item element
const element = document.createElement('li');
// Change HTML code inside created list element using icon we are currently working on
element.innerHTML = `
<li class="list-group-item d-flex align-items-center">
<i class="far fa-${icon.toLowerCase()} fa-3x me-4"></i>${icon}
</li>
`;
// Return ready element
return element;
});
// Add an event listener to the scrollable container. The event below is triggered when a user scrolls to the end of the container
basicElement.addEventListener('completed.mdb.infiniteScroll', () => {
// Return nothing when user appended all of the generated items
if (itemIndex === icons.length - 1) return;
// Append next element to the scrollable container
basicElement.appendChild(items[itemIndex]);
// Increment amount of items that are appended
itemIndex++;
});
// An array of icon names
const icons = [
'Sad-Tear',
'Meh-Blank',
'Smile-Wink',
'Tired',
'Surprise',
'Kiss-Beam',
'Laugh-Squint',
];
// Get a scrollable container using an id attribute
const basicElement = document.getElementById('basic-example');
// An index of elements added after scrolling to the end of the container
let itemIndex = 0;
// items - an array of the created elements using the loop through icons array
const items = icons.map((icon) => {
// Create a list item element
const element = document.createElement('li');
// Change HTML code inside created list element using icon we are currently working on
element.innerHTML = `
<li class="list-group-item d-flex align-items-center">
<i class="far fa-${icon.toLowerCase()} fa-3x me-4"></i>${icon}
</li>
`;
// Return ready element
return element;
});
// Add an event listener to the scrollable container. The event below is triggered when a user scrolls to the end of the container
basicElement.addEventListener('completed.mdb.infiniteScroll', () => {
// Return nothing when user appended all of the generated items
if (itemIndex === icons.length - 1) return;
// Append next element to the scrollable container
basicElement.appendChild(items[itemIndex]);
// Increment amount of items that are appended
itemIndex++;
});
Direction
Use data-mdb-infinite-direction
to define the scrolling direction.
<div
class="py-3 text-center"
id="direction-example"
style="max-width: 1500px; overflow-x: scroll; white-space: nowrap;"
data-mdb-infinite-scroll-init
data-mdb-infinite-direction="x"
>
<span class="mx-5"><i class="far fa-angry fa-3x me-4"></i> Angry</span>
<span class="mx-5"><i class="far fa-dizzy fa-3x me-4"></i> Dizzy</span>
<span class="mx-5"><i class="far fa-flushed fa-3x me-4"></i> Flushed</span>
<span class="mx-5"><i class="far fa-grimace fa-3x me-4"></i> Grimace</span>
<span class="mx-5"><i class="far fa-grin fa-3x me-4"></i> Grin</span>
</div>
import { InfiniteScroll, initMDB } from "mdb-ui-kit";
initMDB({ InfiniteScroll });
// Get a scrollable container using an id attribute
const directionElement = document.getElementById('direction-example');
// An index of elements added after scrolling to the end of the container
let itemIndex = 0;
// An array of icon names
const icons = [
'Sad-Tear',
'Meh-Blank',
'Smile-Wink',
'Tired',
'Surprise',
'Kiss-Beam',
'Laugh-Squint',
];
// items - an array of the created elements using the loop through icons array
const items = icons.map((icon) => {
// Create a span element
const element = document.createElement('span');
// Add class mx-5 to the created element, which defines left and right margin
element.classList.add('mx-5');
// Change HTML code inside created span element using icon we are currently working on
element.innerHTML = `
<i class="far fa-${icon.toLowerCase()} fa-3x me-4"></i>
${icon}
`;
// Return ready element
return element;
});
// Add an event listener to the scrollable container. The event below is triggered when a user scrolls to the end of the container
directionElement.addEventListener('completed.mdb.infiniteScroll', () => {
// Return nothing when user appended all of the generated items
if (itemIndex === items.length - 1) return;
// Append next element to the scrollable container
directionElement.appendChild(items[itemIndex]);
// Increment amount of items that are appended
itemIndex++;
});
// Get a scrollable container using an id attribute
const directionElement = document.getElementById('direction-example');
// An index of elements added after scrolling to the end of the container
let itemIndex = 0;
// An array of icon names
const icons = [
'Sad-Tear',
'Meh-Blank',
'Smile-Wink',
'Tired',
'Surprise',
'Kiss-Beam',
'Laugh-Squint',
];
// items - an array of the created elements using the loop through icons array
const items = icons.map((icon) => {
// Create a span element
const element = document.createElement('span');
// Add class mx-5 to the created element, which defines left and right margin
element.classList.add('mx-5');
// Change HTML code inside created span element using icon we are currently working on
element.innerHTML = `
<i class="far fa-${icon.toLowerCase()} fa-3x me-4"></i>
${icon}
`;
// Return ready element
return element;
});
// Add an event listener to the scrollable container. The event below is triggered when a user scrolls to the end of the container
directionElement.addEventListener('completed.mdb.infiniteScroll', () => {
// Return nothing when user appended all of the generated items
if (itemIndex === items.length - 1) return;
// Append next element to the scrollable container
directionElement.appendChild(items[itemIndex]);
// Increment amount of items that are appended
itemIndex++;
});
Spinners and asynchronous data
<div class="py-3 text-center" id="spinners-and-async-example" data-mdb-infinite-scroll-init style="max-height: 500px; overflow-y: scroll">
<div id="images">
<img src="https://mdbcdn.b-cdn.net/img/Photos/Slides/img%20(100).webp" class="img-fluid mb-3"/>
<img src="https://mdbcdn.b-cdn.net/img/Photos/Slides/img%20(105).webp" class="img-fluid mb-3"/>
<img src="https://mdbcdn.b-cdn.net/img/Photos/Slides/img%20(106).webp" class="img-fluid mb-3"/>
</div>
<div class="spinner-border mx-auto" id="spinner" style="display: none"></div>
</div>
import { InfiniteScroll, initMDB } from "mdb-ui-kit";
initMDB({ InfiniteScroll });
// Get a spinner, container with images and scrollable container using an id attribute
const spinner = document.getElementById('spinner');
const imagesContainer = document.getElementById('images');
const infiniteContainer = document.getElementById('spinners-and-async-example');
// Function that generates image with data from API
const createImg = url => {
// Create an image element
let imgElement = document.createElement('img');
// Add .img-fluid class to the element, it will adjust size of it to the container
imgElement.classList.add('img-fluid');
// Set a src attribute using parameter that is passed to the function
imgElement.setAttribute('src', url);
// Return ready image element
return imgElement;
}
// Function that loads next image
const loadImages = () => {
// Make spinner visible
spinner.style.display = 'block';
// Fetch your API
fetch('YOUR_API/getNextItem')
.then(response => response.json)
.then(imgUrl => {
// Hide spinner after data loads
spinner.style.display = 'none';
// Append an image element generated by createImg function to the container with images
imagesContainer.appendChild(createImg(imgUrl));
});
}
// Add an event listener to the scrollable container. The event below is triggered when a user scrolls to the end of the container
infiniteContainer.addEventListener('completed.mdb.infiniteScroll', loadImages);
// Get a spinner, container with images and scrollable container using an id attribute
const spinner = document.getElementById('spinner');
const imagesContainer = document.getElementById('images');
const infiniteContainer = document.getElementById('spinners-and-async-example');
// Function that generates image with data from API
const createImg = url => {
// Create an image element
let imgElement = document.createElement('img');
// Add .img-fluid class to the element, it will adjust size of it to the container
imgElement.classList.add('img-fluid');
// Set a src attribute using parameter that is passed to the function
imgElement.setAttribute('src', url);
// Return ready image element
return imgElement;
}
// Function that loads next image
const loadImages = () => {
// Make spinner visible
spinner.style.display = 'block';
// Fetch your API
fetch('YOUR_API/getNextItem')
.then(response => response.json)
.then(imgUrl => {
// Hide spinner after data loads
spinner.style.display = 'none';
// Append an image element generated by createImg function to the container with images
imagesContainer.appendChild(createImg(imgUrl));
});
}
// Add an event listener to the scrollable container. The event below is triggered when a user scrolls to the end of the container
infiniteContainer.addEventListener('completed.mdb.infiniteScroll', loadImages);
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
.
<!--Main layout-->
<main class="my-4">
<div class="container">
<!--Section: Posts-->
<section class="text-center mb-4" id="posts">
<div class="row">
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init>
<img
data-mdb-lazy-load-init
data-mdb-lazy-src="https://mdbcdn.b-cdn.net/img/Photos/Others/images/29.webp"
data-mdb-lazy-placeholder="https://placehold.it/1321x583?text=Loading"
class="w-100"
/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);"></div>
</a>
</div>
<h5>This is an title of the article</h5>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Quisquam cupiditate veniam voluptatibus laudantium cum dolorem
illo. Quos architecto deserunt saepe.
</p>
<a class="btn btn-info btn-rounded" href="#!" role="button" data-mdb-ripple-init data-mdb-ripple-color="light">Read more</a>
</div>
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init>
<img
data-mdb-lazy-load-init
data-mdb-lazy-src="https://mdbcdn.b-cdn.net/img/Photos/Others/images/27.webp"
data-mdb-lazy-placeholder="https://placehold.it/1321x583?text=Loading"
class="w-100"
/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);"></div>
</a>
</div>
<h5>This is an title of the article</h5>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Quisquam cupiditate veniam voluptatibus laudantium cum dolorem
illo. Quos architecto deserunt saepe.
</p>
<a class="btn btn-info btn-rounded" href="#!" role="button" data-mdb-ripple-init data-mdb-ripple-color="light">Read more</a>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init>
<img
data-mdb-lazy-load-init
data-mdb-lazy-src="https://mdbcdn.b-cdn.net/img/Photos/Others/images/25.webp"
data-mdb-lazy-placeholder="https://placehold.it/1321x583?text=Loading"
class="w-100"
/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);"></div>
</a>
</div>
<h5>This is an title of the article</h5>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Quisquam cupiditate veniam voluptatibus laudantium cum dolorem
illo. Quos architecto deserunt saepe.
</p>
<a class="btn btn-info btn-rounded" href="#!" role="button" data-mdb-ripple-init data-mdb-ripple-color="light">Read more</a>
</div>
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init>
<img
data-mdb-lazy-load-init
data-mdb-lazy-src="https://mdbcdn.b-cdn.net/img/Photos/Others/images/24.webp"
data-mdb-lazy-placeholder="https://placehold.it/1321x583?text=Loading"
class="w-100"
/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);"></div>
</a>
</div>
<h5>This is an title of the article</h5>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Quisquam cupiditate veniam voluptatibus laudantium cum dolorem
illo. Quos architecto deserunt saepe.
</p>
<a class="btn btn-info btn-rounded" href="#!" role="button" data-mdb-ripple-init data-mdb-ripple-color="light">Read more</a>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init>
<img
data-mdb-lazy-load-init
data-mdb-lazy-src="https://mdbcdn.b-cdn.net/img/Photos/Others/images/31.webp"
data-mdb-lazy-placeholder="https://placehold.it/1321x583?text=Loading"
class="w-100"
/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);"></div>
</a>
</div>
<h5>This is an title of the article</h5>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Quisquam cupiditate veniam voluptatibus laudantium cum dolorem
illo. Quos architecto deserunt saepe.
</p>
<a class="btn btn-info btn-rounded" href="#!" role="button" data-mdb-ripple-init data-mdb-ripple-color="light">Read more</a>
</div>
<div class="col-md-6 mb-4">
<div class="bg-image hover-overlay ripple shadow-1-strong rounded mb-4" data-mdb-ripple-init>
<img
data-mdb-lazy-load-init
data-mdb-lazy-src="https://mdbcdn.b-cdn.net/img/Photos/Others/images/23.webp"
data-mdb-lazy-placeholder="https://placehold.it/1321x583?text=Loading"
class="w-100"
/>
<a href="#!">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.2);"></div>
</a>
</div>
<h5>This is an title of the article</h5>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Quisquam cupiditate veniam voluptatibus laudantium cum dolorem
illo. Quos architecto deserunt saepe.
</p>
<a class="btn btn-info btn-rounded" href="#!" role="button" data-mdb-ripple-init data-mdb-ripple-color="light">Read more</a>
</div>
</div>
<div class="row" id="spinner" style="display: none;">
<div class="col-md-12">
<div class="spinner-border mx-auto"></div>
</div>
</div>
</section>
<!--Section: Posts-->
</div>
</main>
<!--Main layout-->
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) => {
// returns the HTML template with post's title, image & text
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>
`;
};
// posts - array of templates
const posts = items.map((item) => getPostTemplate(item));
const generateRow = (firstPost, secondPost) => {
// Returns a div.row element with two columns generated based on arguments
let el = document.createElement('div');
el.classList.add('row');
el.innerHTML = `
${firstPost}
${secondPost}
`;
return el;
};
// rows - array of rows with two posts each
const rows = [];
// iterates over posts and creates a row for every two of them
for (let i = 0; i < posts.length - 1; i += 2) {
rows.push(generateRow(posts[i], posts[i + 1]));
}
// renderedItems - number of items already rendered
let renderedItems = 0;
const renderItems = (index) => {
// timeout simulates delay in loading items (f.e. API call)
setTimeout(() => {
// hide spinner
spinner.style.display = 'none';
postsContainer.appendChild(rows[index]);
}, 1500);
};
const loadItems = () => {
if (renderedItems < rows.length) {
// show spinner
postsContainer.appendChild(spinner);
spinner.style.display = 'flex';
renderItems(renderedItems);
renderedItems++;
// Removes event listener after all items have been loaded
if (renderedItems === rows.length) {
window.removeEventListener('completed.mdb.infiniteScroll', loadItems);
}
}
};
// load items when window is scrolled to the end
window.addEventListener('completed.mdb.infiniteScroll', loadItems);
// init infinite scroll
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) => {
// returns the HTML template with post's title, image & text
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>
`;
};
// posts - array of templates
const posts = items.map((item) => getPostTemplate(item));
const generateRow = (firstPost, secondPost) => {
// Returns a div.row element with two columns generated based on arguments
let el = document.createElement('div');
el.classList.add('row');
el.innerHTML = `
${firstPost}
${secondPost}
`;
return el;
};
// rows - array of rows with two posts each
const rows = [];
// iterates over posts and creates a row for every two of them
for (let i = 0; i < posts.length - 1; i += 2) {
rows.push(generateRow(posts[i], posts[i + 1]));
}
// renderedItems - number of items already rendered
let renderedItems = 0;
const renderItems = (index) => {
// timeout simulates delay in loading items (f.e. API call)
setTimeout(() => {
// hide spinner
spinner.style.display = 'none';
postsContainer.appendChild(rows[index]);
}, 1500);
};
const loadItems = () => {
if (renderedItems < rows.length) {
// show spinner
postsContainer.appendChild(spinner);
spinner.style.display = 'flex';
renderItems(renderedItems);
renderedItems++;
// Removes event listener after all items have been loaded
if (renderedItems === rows.length) {
window.removeEventListener('completed.mdb.infiniteScroll', loadItems);
}
}
};
// load items when window is scrolled to the end
window.addEventListener('completed.mdb.infiniteScroll', loadItems);
// init infinite scroll
new mdb.InfiniteScroll(window);
Infinite scroll - API
Import
Importing components depends on how your application works. If you intend to use the MDBootstrap ES
format, you must
first import the component and then initialize it with the initMDB
method. If you are going to use the UMD
format,
just import the mdb-ui-kit
package.
import { InfiniteScroll, initMDB } from "mdb-ui-kit";
initMDB({ InfiniteScroll });
import 'mdb-ui-kit';
Usage
Via data attributes
Using the Infinite scroll method doesn't require any additional JavaScript code - simply add
data-mdb-infinite-scroll-init
attribute to
container element
and use other data attributes to set all options.
For ES
format, you must first import and call the initMDB
method.
<div data-mdb-infinite-scroll-init>
Sample content
</div>
Via JavaScript
const infiniteScrollInstance = new InfiniteScroll(document.getElementById('element'), {
infinite-direction: '...',
});
const infiniteScrollInstance = new mdb.InfiniteScroll(document.getElementById('element'), {
infinite-direction: '...',
});
Via jQuery
Note: By default, MDB does not include jQuery and you have to add it to the project on your own.
$(document).ready(() => {
$('.example-class').infiniteScroll(options);
});
Options
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to
data-mdb-
, as in data-mdb-infinite-direction="y"
.
Name | Type | Default | Description |
---|---|---|---|
infiniteDirection
|
String | 'y' |
Defines an example scroll direction. |
Methods
Name | Description | Example |
---|---|---|
dispose
|
Removes an instance of the lazy element |
infiniteScrollInstance.toggle()
|
getInstance
|
Static method which allows you to get the infinite scroll instance associated to a DOM element. |
InfiniteScroll.getInstance(infiniteScrollElement)
|
getOrCreateInstance
|
Static method which returns the infinite scroll instance associated to a DOM element or create a new one in case it wasn't initialized. |
InfiniteScroll.getOrCreateInstance(infiniteScrollElement)
|
const infiniteScrollElement = document.getElementById('element');
const infiniteScrollInstance = new InfiniteScroll(infiniteScrollElement);
infiniteScrollInstance.dispose();
const infiniteScrollElement = document.getElementById('element');
const infiniteScrollInstance = new mdb.InfiniteScroll(infiniteScrollElement);
infiniteScrollInstance.dispose();
Events
Name | Description |
---|---|
completed.mdb.infiniteScroll
|
This event fires immediately after scrolling to the end of the container. |
const infiniteScrollElement = document.getElementById('element');
infiniteScrollElement.addEventListener('completed.mdb.infiniteScroll', (e) => {
// do something...
});