<h1>Infinite Scroll v4 - Loading JSON + Masonry</h1>

<p>Loading photos from the <a href="https://unsplash.com/developers?utm_source=infinite-scroll-demos&utm_medium=referral&utm_campaign=api-credit">Unsplash API</a></p>

<div class="grid">
  <div class="grid__col-sizer"></div>
  <div class="grid__gutter-sizer"></div>
</div>

<div class="page-load-status">
  <div class="loader-ellips infinite-scroll-request">
    <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>
  <p class="infinite-scroll-last">End of content</p>
  <p class="infinite-scroll-error">No more pages to load</p>
</div>
body {
  font-family: sans-serif;
  line-height: 1.4;
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.grid__col-sizer,
.photo-item {
  width: 32%;
}

.grid__gutter-sizer {
  width: 2%;
}

.photo-item {
  margin-bottom: 10px;
  float: left;
}

.photo-item__image {
  display: block;
  max-width: 100%;
}

.photo-item__caption {
  position: absolute;
  left: 10px;
  bottom: 10px;
  margin: 0;
}

.photo-item__caption a {
  color: white;
  font-size: 0.8em;
  text-decoration: none;
}

.page-load-status {
  display: none; /* hidden by default */
  padding-top: 20px;
  border-top: 1px solid #DDD;
  text-align: center;
  color: #777;
}

/* loader ellips in separate pen CSS */
let $grid = $('.grid').masonry({
  itemSelector: '.photo-item',
  columnWidth: '.grid__col-sizer',
  gutter: '.grid__gutter-sizer',
  percentPosition: true,
  stagger: 30,
  // nicer reveal transition
  visibleStyle: { transform: 'translateY(0)', opacity: 1 },
  hiddenStyle: { transform: 'translateY(100px)', opacity: 0 },
});

//------------------//

// Get an API key for your demos at https://unsplash.com/developers
const unsplashID = '9ad80b14098bcead9c7de952435e937cc3723ae61084ba8e729adb642daf0251';

// get Masonry instance
var msnry = $grid.data('masonry');

$grid.infiniteScroll({
  path: function() {
    return `https://api.unsplash.com/photos?client_id=${unsplashID}&page=${this.pageIndex}`;
  },
  // load response as JSON
  responseBody: 'json',
  outlayer: msnry,
  status: '.page-load-status',
  history: false,
});

$grid.on( 'load.infiniteScroll', function( event, body ) {
  // compile body data into HTML
  let itemsHTML = body.map( getItemHTML ).join('');
  // convert HTML string into elements
  let $items = $( itemsHTML );
  // append item elements
  $items.imagesLoaded( function() {
    $grid.append( $items ).masonry( 'appended', $items );
  })
});

// load initial page
$grid.infiniteScroll('loadNextPage');

//------------------//

function getItemHTML({ user, urls }) {
  return `<div class="photo-item">
    <img class="photo-item__image" src="${urls.regular}" alt="Photo by ${user.name}" />
    <p class="photo-item__caption">
      <a href="${user.links.html}?utm_source=infinite-scroll-demos&utm_medium=referral&utm_campaign=api-credit">${user.name}</a>
    </p>
  </div>`;
}

External CSS

  1. https://codepen.io/desandro/pen/owWLYz.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js
  2. https://unpkg.com/infinite-scroll@4/dist/infinite-scroll.pkgd.js
  3. https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.js