How to Load More Posts using Ajax with a Button or on Scroll in WordPress


Updated: 22/01/2021 – Further clarification has been added on the setup of this script.

In today’s post, we will show you how to create a load more button to show additional posts or custom post types using AJAX.

The benefit of this is that it will improve the page-load of the particular page as it will only be displaying a certain amount of posts before having to load any more of the content (especially when you are loading images).

So let’s get started…

So the first thing that you should have is a list of posts to display on the frontend as follows:-

<code class="language-PHP">
    &lt;div id="ajax-posts" class="row"&gt;
        &lt;?php
            $postsPerPage = 3;
            $args = array(
                    'post_type' =&gt; 'post',
                    'posts_per_page' =&gt; $postsPerPage,
            );

            $loop = new WP_Query($args);

            while ($loop-&gt;have_posts()) : $loop-&gt;the_post();
        ?&gt;

         &lt;div class="small-12 large-4 columns"&gt;
                &lt;h1&gt;&lt;?php the_title(); ?&gt;&lt;/h1&gt;
                &lt;p&gt;&lt;?php the_content(); ?&gt;&lt;/p&gt;
         &lt;/div&gt;

         &lt;?php
                endwhile;
        wp_reset_postdata();
         ?&gt;
    &lt;/div&gt;
    &lt;div id="more_posts"&gt;Load More&lt;/div&gt;
</code>

Then you want to add the following code in your functions.php file where you register the scripts:


<code class="language-PHP">
	wp_localize_script( 'core-js', 'ajax_posts', array(
	    'ajaxurl' =&gt; admin_url( 'admin-ajax.php' ),
	    'noposts' =&gt; __('No older posts found', 'twentyfifteen'),
	));	
</code>

NOTE: You will need to replace code-js with the file you are going to be adding the JS code later in this tutorial.

We added it to a file called core.js, and the reason we added code-js is that we enqueued the script as follows:

<code class="language-PHP">
	wp_register_script( 'core-js', get_template_directory_uri() . '/assets/js/core.js');
	wp_enqueue_script( 'core-js' );
</code>

Right after the existing wp_localize_script. This will load WordPress own admin-ajax.php so that we can use it when we call it in our ajax call.

ПОЛЕЗНО  Contact Form 7: разрешаем выполнение шорткодов

At the end of the functions.php file, you need to add the function that will load your posts:-

<code class="language-PHP">
function more_post_ajax(){

    $ppp = (isset($_POST["ppp"])) ? $_POST["ppp"] : 3;
    $page = (isset($_POST['pageNumber'])) ? $_POST['pageNumber'] : 0;

    header("Content-Type: text/html");

    $args = array(
        'suppress_filters' =&gt; true,
        'post_type' =&gt; 'post',
        'posts_per_page' =&gt; $ppp,
        'paged'    =&gt; $page,
    );

    $loop = new WP_Query($args);

    $out = '';

    if ($loop -&gt; have_posts()) :  while ($loop -&gt; have_posts()) : $loop -&gt; the_post();
        $out .= '&lt;div class="small-12 large-4 columns"&gt;
                &lt;h1&gt;'.get_the_title().'&lt;/h1&gt;
                &lt;p&gt;'.get_the_content().'&lt;/p&gt;
         &lt;/div&gt;';

    endwhile;
    endif;
    wp_reset_postdata();
    die($out);
}

add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');
</code>

The final part is the ajax itself. In functions.js or your main JavaScript/jQuery file, you need to input inside the $(document).ready(); environment the following code:-

<code class="language-JS">
var ppp = 3; // Post per page
var pageNumber = 1;


function load_posts(){
    pageNumber++;
    var str = '&amp;pageNumber=' + pageNumber + '&amp;ppp=' + ppp + '&amp;action=more_post_ajax';
    $.ajax({
        type: "POST",
        dataType: "html",
        url: ajax_posts.ajaxurl,
        data: str,
        success: function(data){
            var $data = $(data);
            if($data.length){
                $("#ajax-posts").append($data);
                $("#more_posts").attr("disabled",false);
            } else{
                $("#more_posts").attr("disabled",true);
            }
        },
        error : function(jqXHR, textStatus, errorThrown) {
            $loader.html(jqXHR + " :: " + textStatus + " :: " + errorThrown);
        }

    });
    return false;
}

$("#more_posts").on("click",function(){ // When btn is pressed.
    $("#more_posts").attr("disabled",true); // Disable the button, temp.
    load_posts();
    $(this).insertAfter('#ajax-posts'); // Move the 'Load More' button to the end of the the newly added posts.
});
</code>

With the above code, you should now have a load more button at the bottom of your posts, and once you click this it will display further posts. This can also be used with CTP (custom post type).

ПОЛЕЗНО  Load a script just to custom post type in admin

How to add Infinite Load, instead of Click

You can also load the rest of the posts automatically on scroll instead of having to click on a button. This can be achieved by making it invisible by setting the visibility to hidden.

The following code will run the load_posts() function when you’re 100px from the bottom of the page. So instead of the click function we added we would use:

<code class="language-JS">
$(window).on('scroll', function(){
    if($('body').scrollTop()+$(window).height() &gt; $('footer').offset().top){
        if(!($loader.hasClass('post_loading_loader') || $loader.hasClass('post_no_more_posts'))){
                load_posts();
        }
    }
});
</code>

Do note that there is a drawback to this. With this method, you could never scroll the value of $(document).height() - 100 or $('footer').offset().top, If that should happen, just increase the number where the scroll goes to.

You can easily check it by putting console.log in your code and see in the inspector what they throw out like so:

<code class="language-JS">
$(window).on('scroll', function () {
    console.log($(window).scrollTop() + $(window).height());
    console.log($(document).height() - 100);
    if ($(window).scrollTop() + $(window).height()  &gt;= $(document).height() - 100) {
        load_posts();        
    }
});
</code>

Adjust the settings accordingly and you will get this working to your desire in no time!

If you need any help with this, feel free to get in touch in the comment below. If you need help with this, just drop me a message and I’ll be more than happy to help you