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('infiniteScroll')
.
// main.js
var InfiniteScroll = require('infinite-scroll');
var 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
var $ = require('jquery');
var jQueryBridget = require('jquery-bridget');
var 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
var Masonry = require('masonry-layout');
var InfiniteScroll = require('infinite-scroll');
var imagesLoaded = require('imagesloaded');
// init Masonry
var msnry = new Masonry( '.container', {...});
// make imagesLoaded available for InfiniteScroll
InfiniteScroll.imagesLoaded = imagesLoaded;
// now you can use outlayer option
var infScroll = new InfiniteScroll( '.container', {
// options...
outlayer: msnry,
});
Requirejs
Infinite Scroll supports RequireJS.
You can require infinite-scroll.pkgd.js.
requirejs( [
'path/to/infinite-scroll.pkgd.js',
], function( InfiniteScroll ) {
var infScroll = new InfiniteScroll( '.container', {...});
});
To use Infinite Scroll as a jQuery plugin with RequireJS and infinite-scroll.pkgd.js, you need to call jQuery Bridget.
// require the require function
requirejs( [ 'require', 'jquery', 'path/to/infinite-scroll.pkgd.js' ],
function( require, $, InfiniteScroll ) {
// require jquery-bridget, it's included in infinite-scroll.pkgd.js
require( [ 'jquery-bridget/jquery-bridget' ],
function( jQueryBridget ) {
// make Infinite Scroll a jQuery plugin
jQueryBridget( 'infiniteScroll', InfiniteScroll, $ );
// now you can use $().infiniteScroll()
$('.container').infiniteScroll({...});
});
});
Or, you can require Infinite Scroll's index.js by using a package manager: npm, Bower, or Yarn. Set baseUrl
to the package install path and set a config path for all your application code.
requirejs.config({
baseUrl: 'node_modules/', // npm install path
paths: {
app: '../'
},
});
requirejs( [
'infinite-scroll/js/index',
'app/my-component.js',
], function( InfiniteScroll, myComp ) {
var infScroll = new InfiniteScroll( '.container', {...});
});
You can require dependencies and use Infinite Scroll as a jQuery plugin with jQuery Bridget.
requirejs.config({
baseUrl: 'node_modules/',
paths: {
jquery: 'jquery/jquery'
},
});
requirejs( [
'jquery',
'infinite-scroll/js/index',
'jquery-bridget/jquery-bridget',
],
function( $, InfiniteScroll ) {
// make Infinite Scroll a jQuery plugin
$.bridget( 'infiniteScroll', InfiniteScroll, $ );
// now you can use $().infiniteScroll()
$('.container').infiniteScroll({...});
});
Infinite Scroll does not include imagesLoaded
, which is required to use outlayer
. You will need to install and require imagesLoaded
separately.
requirejs.config({
baseUrl: 'node_modules/', // npm install path
paths: {
app: '../'
},
});
requirejs( [
'masonry-layout/masonry',
'imagesloaded/imagesloaded',
'infinite-scroll/js/index',
'app/my-component.js',
], function( Masonry, imagsLoaded InfiniteScroll, myComp ) {
// init Masonry
var msnry = new Masonry( '.container', {...});
// make imagesLoaded available for Infinite Scroll
InfiniteScroll.imagesLoaded = imagesLoaded;
// now you can use outlayer option
var 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.
var $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 );
});
Edit this demo or vanilla JS demo on CodePen
See additional demos:
Button behaviors
Click button to start loading on scroll
var $container = $('.container').infiniteScroll({
// options...
// disable loading on scroll
loadOnScroll: false,
});
var $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
var $container = $('.container').infiniteScroll({
// options...
// enable button
button: '.view-more-button',
});
var $viewMoreButton = $('.view-more-button');
// get Infinite Scroll instance
var 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
.
var nextURL;
function updateNextURL( doc ) {
nextURL = $( doc ).find('.pagination__next').attr('href');
}
// get initial nextURL
updateNextURL( document );
// init Infinite Scroll
var $container = $('.container').infiniteScroll({
// use function to set custom URLs
path: function() {
return nextURL;
},
});
// update nextURL on page load
$container.on( 'load.infiniteScroll', function( event, response ) {
updateNextURL( response );
});
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 /
var 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 v3 supports IE/Edge 11, Android 4+, Safari for iOS 8+, Firefox 29+, and Chrome 33+.
WordPress Plugin
The official WordPress plugin for Infinite Scroll v3 is in the works. Until then, you can continue using the previous Infinite Scroll v2 WordPress plugin.
Upgrading from v2
Infinite Scroll v3 is a complete rewrite with all new API and behavior. Upgrading from v2 to v3 will require making several changes.
jquery.infinitescroll.js
andjquery.infinite-scroll.min.js
files have been replaced withdist/infinite-scroll.pkgd.js
anddist/infinite-scroll.pkgd.min.js
.infinitescroll()
jQuery plugin renamed to camelCased.infiniteScroll()
.- The callback function has been removed.
Use
append
orload
event. For Masonry, useoutlayer
.
Upgrading v2 options
itemSelector
: Useappend
to select items to append.nextSelector
: Setpath
to a selector string of a link to the next page to use itshref
value. UsehideNav
to hide navigation.binder
: UseelementScroll
to scroll within an element.path
:path
works differently.pathParse
: Usepath
.prefill
: Backwards compatible, works in v3.dataType
: UseresponseType
to load data content like JSON.animate
&extraScrollPx
: Scrolling animation has been removed in v3.maxPage
: removed in v3. Use conditional event logic, like in scroll 2 pages then button example.appendCallback
: Useappend
event.errorCallback
: Useerror
event.debug
: Backwards compatible, works in v3.loading
finished
: Useload
event.finishedMsg
: Usestatus
and set message HTML in.infinite-scroll-error
and.infinite-scroll-last
.img
&msgText
: Usestatus
and set loading HTML in.infinite-scroll-request
.
Upgrading v2 methods
pause
,resume
, &toggle
: Enable and disableloadOnScroll
option.bind
&unbind
: Disable and re-setscrollThreshold
option.retrieve
: UseloadNextPage
.update
: Useoption
.destroy
: Backward compatible, works in v3.
v2 upgrade example
// Infinite Scroll v2
$('.container').infinitescroll({
itemSelector: '.post',
nextSelector: '.pagination__next',
loading: {
img: '/loading.gif',
msgText: 'Loading...',
finished: 'Congratulations, you have reached the end of the internet',
},
// callback
}, function( items ) {
$( items ).tooltip();
});
// Infinite Scroll v3
var $container = $('.container').infiniteScroll({
append: '.post',
path: '.pagination__next',
status: '.page-load-status',
});
// use event for v2 callback
$container.on( 'append.infiniteScroll', function( event, response, path, items ) {
$( items ).tooltip();
});
<div class="container">
<<article class="post">...</article>">...</div>
<<article class="post">...</article>">...</div>
...
</div>
<!-- use status element for v2 loading options -->
<div class="page-load-status">
<div class="infinite-scroll-request">
<img src="/loading.gif" alt="Loading" />
Loading...
</div>
<p class="infinite-scroll-error infinite-scroll-last">
Congratulations, you have reached the end of the internet
</p>
</div>
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.