Extras
Module loaders
Webpack & Browserify
Install Infinite Scroll with npm or Yarn.
# npm
npm install infinite-scroll
# Yarn
yarn add infinite-scroll
You can then require('infinite-scroll')
.
// main.js
const InfiniteScroll = require('infinite-scroll');
let infScroll = new InfiniteScroll( '.container', {
// options...
});
Compile your JS with Webpack or Browserify.
# Webpack
webpack main.js bundle.js
# Browserify
browserify main.js -o bundle.js
To use Infinite Scroll as a jQuery plugin, you need to call jQuery Bridget.
# npm
npm install jquery-bridget
# Yarn
yarn add jquery-bridget
// main.js
const $ = require('jquery');
const jQueryBridget = require('jquery-bridget');
const InfiniteScroll = require('infinite-scroll');
// make Infinite Scroll a jQuery plugin
jQueryBridget( 'infiniteScroll', InfiniteScroll, $ );
// now you can use $().infiniteScroll()
$('.container').infiniteScroll({...});
When installed with a package manager, Infinite Scroll does not include imagesLoaded
, which is required to use outlayer
. You will need to install and require imagesLoaded
separately.
# npm
npm install imagesloaded
# Yarn
yarn add imagesloaded
// main.js
const Masonry = require('masonry-layout');
const InfiniteScroll = require('infinite-scroll');
const imagesLoaded = require('imagesloaded');
// init Masonry
let msnry = new Masonry( '.container', {...});
// make imagesLoaded available for InfiniteScroll
InfiniteScroll.imagesLoaded = imagesLoaded;
// now you can use outlayer option
let infScroll = new InfiniteScroll( '.container', {
// options...
outlayer: msnry,
});
Loading JSON
Here is one example of how to use Infinite Scroll to load JSON data and append content. We'll use the Unsplash API to load pages of photos.
let $container = $('.container').infiniteScroll({
path: function() {
return 'https://api.unsplash.com/photos?client_id=...&page=' + this.pageIndex;
},
// load page as JSON
responseBody: 'json',
// disable history
history: false,
});
$container.on( 'load.infiniteScroll', function( event, body ) {
// body is JSON, put that data into template
let itemsHTML = template.compile( body );
// convert to jQuery object
let $items = $( itemsHTML );
// append items
$container.append( $items );
});
Edit this demo or vanilla JS demo on CodePen
See additional demos:
Button behaviors
Click button to start loading on scroll
let $container = $('.container').infiniteScroll({
// options...
// disable loading on scroll
loadOnScroll: false,
});
let $viewMoreButton = $('.view-more-button');
$viewMoreButton.on( 'click', function() {
// load next page
$container.infiniteScroll('loadNextPage');
// enable loading on scroll
$container.infiniteScroll( 'option', {
loadOnScroll: true,
});
// hide button
$viewMoreButton.hide();
});
Edit this demo or vanilla JS demo on CodePen
Scroll 2 pages, then load with button
let $container = $('.container').infiniteScroll({
// options...
// enable button
button: '.view-more-button',
});
let $viewMoreButton = $('.view-more-button');
// get Infinite Scroll instance
let infScroll = $container.data('infiniteScroll');
$container.on( 'load.infiniteScroll', onPageLoad );
function onPageLoad() {
if ( infScroll.loadCount == 1 ) {
// after 2nd page loaded
// disable loading on scroll
$container.infiniteScroll( 'option', {
loadOnScroll: false,
});
// show button
$viewMoreButton.show();
// remove event listener
$container.off( 'load.infiniteScroll', onPageLoad );
}
}
Edit this demo or vanilla JS demo on CodePen
Loading URLs from loaded pages
You can use Infinite Scroll to load the next article page by updating the next URL from the loaded page. For example, the current URL is /news/alpha
, and its next link /news/beta
; and when you load /news/beta
, its next link is /news/gamma
.
To do so, you can use a nextURL
variable and update it on load
, then set path
to a function to return nextURL
.
let nextURL;
function updateNextURL( doc ) {
nextURL = $( doc ).find('.pagination__next').attr('href');
}
// get initial nextURL
updateNextURL( document );
// init Infinite Scroll
let $container = $('.container').infiniteScroll({
// use function to set custom URLs
path: function() {
return nextURL;
},
});
// update nextURL on page load
$container.on( 'load.infiniteScroll', function( event, body ) {
updateNextURL( body );
});
Loading animations
Feel free to use these loading animations within .infinite-scroll-request
status element.
<div class="loader-ellips">
<span class="loader-ellips__dot"></span>
<span class="loader-ellips__dot"></span>
<span class="loader-ellips__dot"></span>
<span class="loader-ellips__dot"></span>
</div>
.loader-ellips {
font-size: 20px; /* change size here */
position: relative;
width: 4em;
height: 1em;
margin: 10px auto;
}
.loader-ellips__dot {
display: block;
width: 1em;
height: 1em;
border-radius: 0.5em;
background: #555; /* change color here */
position: absolute;
animation-duration: 0.5s;
animation-timing-function: ease;
animation-iteration-count: infinite;
}
.loader-ellips__dot:nth-child(1),
.loader-ellips__dot:nth-child(2) {
left: 0;
}
.loader-ellips__dot:nth-child(3) { left: 1.5em; }
.loader-ellips__dot:nth-child(4) { left: 3em; }
@keyframes reveal {
from { transform: scale(0.001); }
to { transform: scale(1); }
}
@keyframes slide {
to { transform: translateX(1.5em) }
}
.loader-ellips__dot:nth-child(1) {
animation-name: reveal;
}
.loader-ellips__dot:nth-child(2),
.loader-ellips__dot:nth-child(3) {
animation-name: slide;
}
.loader-ellips__dot:nth-child(4) {
animation-name: reveal;
animation-direction: reverse;
}
<div class="loader-wheel">
<i><i><i><i><i><i><i><i><i><i><i><i>
</i></i></i></i></i></i></i></i></i></i></i></i>
</div>
.loader-wheel {
font-size: 64px; /* change size here */
position: relative;
height: 1em;
width: 1em;
padding-left: 0.45em;
overflow: hidden;
margin: 0 auto;
animation: loader-wheel-rotate 0.5s steps(12) infinite;
}
.loader-wheel i {
display: block;
position: absolute;
height: 0.3em;
width: 0.1em;
border-radius: 0.05em;
background: #333; /* change color here */
opacity: 0.8;
transform: rotate(-30deg);
transform-origin: center 0.5em;
}
@keyframes loader-wheel-rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
Google Analytics
Use Infinite Scroll events to track pageviews with Google Analytics.
With history
option enabled, use the history
event.
$container.on( 'history.infiniteScroll', function() {
ga( 'set', 'page', location.pathname );
ga( 'send', 'pageview' );
});
With history
option disabled, use the append
or load
event.
// link used to get absolute path, beginning with /
let link = document.createElement('a');
$container.on( 'append.infiniteScroll', function( event, response, path ) {
link.href = path;
ga( 'set', 'page', link.pathname );
ga( 'send', 'pageview' );
});
Browser support
Infinite Scroll v4 supports Chrome 60+, Edge 79+, Firefox 55+, Safari 11+.
For IE10 and Android 4 support, try Infinite Scroll v3.
Upgrading from v3
Infinite Scroll v4 is mostly backwards compatible with v3.
The one breaking change is that Infinite Scroll v4 removed responseType
option in favor of responseBody
. This change effects loading JSON in particular. To load JSON with Infinite Scroll v4, set responseBody: 'json'
in your options. Then the body
argument in the load event will be JSON.
// Infinite Scroll v3
let $container = $('.container').infiniteScroll({
path: function() {
return 'https://api.unsplash.com/photos?client_id=...&page=' + this.pageIndex;
},
// load page as text
responseType: 'text',
// disable history
history: false,
});
$container.on( 'load.infiniteScroll', function( event, response ) {
// parse response text into JSON data
var data = JSON.parse( response );
// put that data into template
var itemsHTML = template.compile( data );
// convert to jQuery object
var $items = $( itemsHTML );
// append items
$container.infiniteScroll( 'appendItems', $items );
});
// Infinite Scroll v4
let $container = $('.container').infiniteScroll({
path: function() {
return 'https://api.unsplash.com/photos?client_id=...&page=' + this.pageIndex;
},
// load page as json
responseBody: 'json',
// disable history
history: false,
});
$container.on( 'load.infiniteScroll', function( event, body ) {
// body is JSON data
var itemsHTML = template.compile( body );
// convert to jQuery object
var $items = $( itemsHTML );
// append items
$container.infiniteScroll( 'appendItems', $items );
});
New features
- Uses fetch API to make requests
loadNextPage
returns a Promise- Set headers and fetch options with
fetchOptions
- 10% smaller filesize
- Internet Explorer support dropped
Issues
Reduced test cases
Creating a reduced test case is the best way to debug problems and report issues. Read CSS Tricks on why they’re so great.
Create a reduced test case for Infinite Scroll by forking any one of the CodePen demos from these docs.
- A reduced test case clearly demonstrates the bug or issue.
- It contains the bare minimum HTML, CSS, and JavaScript required to demonstrate the bug.
- A link to your production site is not a reduced test case.
Creating a reduced test case is the best way to get your issue addressed. They help you point out the problem. They help us debug the problem. They help others understand the problem.
Submitting issues
Report issues on GitHub. Make sure to include a reduced test case. Without a reduced test case, your issue may be closed.
Feature requests
Help us select new features by looking over requested features on the GitHub issue tracker and adding your +1 reaction to features you’d like to see added.