Ad

How Can I Create An Infinite Scroll (lazy Loading) Grouped Per Day And Showing Date?

Situation

I'm creating a custom Wordpress website where I want to show the most recent articles grouped by day and have it scroll infinitely when you've reached the bottom of your screen.

Problem

I don't know how to continue with the date you were on without breaking the layout. I've seen many code that involve having infinite scroll, but none of them really worked for me since it also needs to match the design. Here is the design:

enter image description here

The image pretty much explains what I need to create and so I've written the following code:

<div class="recent">
<?php 

$args = array(
  'posts_per_page' => -1, 
  'orderby' => 'date' 
);
$myQuery = new WP_Query($args);

$date = '';
$postCount = 0;
$newDay = false;

if ( $myQuery->have_posts() ) : while ( $myQuery->have_posts() ) : $myQuery->the_post();

$postCount++;
if ( $date != get_the_date() ) {
  if ( $postCount != 1 ) {
    $newDay = false;

    if (!$newDay) {
      ?></div><?php
    }
  ?>
    </div>
  <?php
  }
  ?>
    <div class="recent__articles">
  <?php
  $newDay = true;
  $date = get_the_date();
  ?>
      <div class="recent__header">
        <img class="header__icon" src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/time.svg" alt="time-icon">
        <?php echo $date; ?>
      </div>
  <?php
  if ($newDay) {
    ?>
      <div class="articles__wrapper"><?php
  }
}
?>
        <div class="recent__article">
          <a target="_blank" rel="nofollow noreferrer" href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
            <figure class="article__image">
            <?php if ( has_post_thumbnail() ) :
                the_post_thumbnail();
              else : ?>
                <img src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/article-placeholder.png" alt="image-placeholder">
              <?php endif ?>
            </figure>
            <div class="article__meta">
              <span class="article__cat">
                <?php 
                foreach((get_the_category()) as $category){
                  echo $category->name;
                }
                ?>
              </span>
              <h2 class="article__title"><?php echo get_the_title() ?></h2>
              <div class="article__date">
                <?php echo esc_html( time_difference( get_the_time('U'), current_time('timestamp') ) ); ?>
              </div>
            </div>
          </a>
        </div>
  <?php
  endwhile; endif;
  wp_reset_postdata();
  ?>
</div>

Top part where I check the date and increment the postCount is so I can group the articles of that day in separate div and style it accordingly.

Now all I need is to check wether I've reached the bottom and continue with where I left off.

Any help with the directions I need to be going is much appreciated.

Thank you!

Ad

Answer

I've fixed my problem in combination with the Ajax Load More plugin. I hope this will help others facing the same problem as I did. If anybody sees improvement in my code, I'd much appreciate it.

Tested on: MacOS - Chrome/Safari/Firefox & iOS - Chrome/Safari

  1. I've installed the Ajax Load More plugin
  2. They have a Repeat Templates section which is basically the while loop in php and I've added the following code (a bit stripped from what I've showed here above).
<?php $postCount++;

if ( $date != get_the_date() ) {
  if ( $postCount != 1 ) {
    $newDay = false;

    if (!$newDay) {
      ?></div><?php
    }
  ?>
    </div>
  <?php
  }
  ?>
    <div class="recent__articles">
  <?php
  $newDay = true;
  $date = get_the_date();
  ?>
      <div class="recent__header">
        <img class="header__icon" src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/time.svg" alt="time-icon">
        <?php echo $date; ?>
      </div>
  <?php
  if ($newDay) {
    ?>
      <div class="articles__wrapper"><?php
  }
}
?>
        <div class="recent__article">
          <a target="_blank" rel="nofollow noreferrer" href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
            <figure class="article__image">
            <?php if ( has_post_thumbnail() ) :
                the_post_thumbnail();
              else : ?>
                <img src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/article-placeholder.png" alt="image-placeholder">
              <?php endif ?>
            </figure>
            <div class="article__meta">
              <span class="article__cat">
                <?php 
                foreach((get_the_category()) as $category){
                  echo $category->name;
                }
                ?>
              </span>
              <h2 class="article__title"><?php echo get_the_title() ?></h2>
              <div class="article__date">
                <?php echo esc_html( time_difference( get_the_time('U'), current_time('timestamp') ) ); ?>
              </div>
            </div>
          </a>
        </div>
  1. I've a .php file that I load in somewhere els that looks like this:
<div class="recent">
  <?php

    $date = '';
    $postCount = 0;
    $newDay = false;
    echo do_shortcode("[ajax_load_more post_type='post' posts_per_page='2' scroll_distance='0']");
  ?>
</div>
  1. Now for the last part I've written the following in jQuery:
  // Ajax load more fix
  function ajaxShowMore() {
    var oldXHR = window.XMLHttpRequest;

    function newXHR() {
        var realXHR = new oldXHR();
        realXHR.addEventListener("readystatechange", function() {
            if (realXHR.readyState === 4) { // When the Ajax call is finished new content is loaded
              var oldRecentHeaders = $('.recent__header'); // Store all previous recent headers in variable

              setTimeout(function() { // Set a timeout, since it goes a bit to fast to store the data
                var newRecentHeaders = $('.recent__header'); // Store all the headers in a variable
                newRecentHeaders.splice(0, oldRecentHeaders.length); // Splice it, so you only get the new added headers

                if (newRecentHeaders.first().text() === oldRecentHeaders.last().text()) { // Check if the first of new header date is the same as the last of the old header date
                  var newArticles = newRecentHeaders.first().parent().find('.articles__wrapper').children(); // Store all the articles

                  newRecentHeaders.first().parent().remove(); // Remove the first new added articles
                  oldRecentHeaders.last().parent().find('.articles__wrapper').append(newArticles); // Add them here
                }
              }, 10);
            }
        }, false);

        return realXHR;
    }

    window.XMLHttpRequest = newXHR;
  }

So for me this specific solution works, based on the classes and structure of my project I've set.

I hope this helps

Ad
source: stackoverflow.com
Ad