donglao7947 2015-07-23 12:21
浏览 76
已采纳

在WordPress中加载更多帖子Ajax按钮

I've had a look through the old questions and tried many of the different methods that there seems to be to do this. The closest I've got to working is this one here: How to implement pagination on a custom WP_Query Ajax

I've tried everything and it just doesnt work. Absolutely nothing changes on the page. If you inspect the Load More Button and click it, the jquery is making the Load More Button action as it changes from <a id="more_posts">Load More</a> to <a id="more_posts" disables="disabled">Load More</a> which even that doesnt seem right to me anyway. It's not adding the posts, I think I'm missing something simple but for the life of me I can't work it out.

The Code in My template file is:

<div id="ajax-posts" class="row">
    <?php 
    $postsPerPage = 3;
    $args = [
        'post_type' => 'post',
        'posts_per_page' => $postsPerPage,
        'cat' => 1
    ];

    $loop = new WP_Query($args);

    while ($loop->have_posts()) : $loop->the_post(); ?>
        <div class="small-12 large-4 columns">
            <h1><?php the_title(); ?></h1>
            <p><?php the_content(); ?></p>
        </div>
        <?php
    endwhile; 

    echo '<a id="more_posts">Load More</a>';

    wp_reset_postdata(); 
    ?>
</div>

The Code in my functions file is:

function more_post_ajax(){
    $offset = $_POST["offset"];
    $ppp = $_POST["ppp"];

    header("Content-Type: text/html");
    $args = [
        'suppress_filters' => true,
        'post_type' => 'post',
        'posts_per_page' => $ppp,
        'cat' => 1,
        'offset' => $offset,
    ];

    $loop = new WP_Query($args);

    while ($loop->have_posts()) { $loop->the_post(); 
        the_content();
    }
    exit; 
}

add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax'); 
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');

And My JQuery in the footer is:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
    jQuery(document).ready( function($) {
        var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";

        // What page we are on.
        var page = 5; 
        // Post per page
        var ppp = 3; 

        $("#more_posts").on("click", function() {
            // When btn is pressed.
            $("#more_posts").attr("disabled",true);

            // Disable the button, temp.
            $.post(ajaxUrl, {
                action: "more_post_ajax",
                offset: (page * ppp) + 1,
                ppp: ppp
            })
            .success(function(posts) {
                page++;
                $("#ajax-posts").append(posts);
                // CHANGE THIS!
                $("#more_posts").attr("disabled", false);
            });
        });
    });
</script>

Can anybody see something I'm missing or able to help?

  • 写回答

1条回答 默认 最新

  • dqlxtv1452 2015-07-23 13:12
    关注

    UPDATE 24.04.2016.

    I've created tutorial on my page https://madebydenis.com/ajax-load-posts-on-wordpress/ about implementing this on Twenty Sixteen theme, so feel free to check it out :)

    EDIT

    I've tested this on Twenty Fifteen and it's working, so it should be working for you.

    In index.php (assuming that you want to show the posts on the main page, but this should work even if you put it in a page template) I put:

        <div id="ajax-posts" class="row">
            <?php
                $postsPerPage = 3;
                $args = array(
                        'post_type' => 'post',
                        'posts_per_page' => $postsPerPage,
                        'cat' => 8
                );
    
                $loop = new WP_Query($args);
    
                while ($loop->have_posts()) : $loop->the_post();
            ?>
    
             <div class="small-12 large-4 columns">
                    <h1><?php the_title(); ?></h1>
                    <p><?php the_content(); ?></p>
             </div>
    
             <?php
                    endwhile;
            wp_reset_postdata();
             ?>
        </div>
        <div id="more_posts">Load More</div>
    

    This will output 3 posts from category 8 (I had posts in that category, so I used it, you can use whatever you want to). You can even query the category you're in with

    $cat_id = get_query_var('cat');
    

    This will give you the category id to use in your query. You could put this in your loader (load more div), and pull with jQuery like

    <div id="more_posts" data-category="<?php echo $cat_id; ?>">>Load More</div>
    

    And pull the category with

    var cat = $('#more_posts').data('category');
    

    But for now, you can leave this out.

    Next in functions.php I added

    wp_localize_script( 'twentyfifteen-script', 'ajax_posts', array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
        'noposts' => __('No older posts found', 'twentyfifteen'),
    ));
    

    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.

    At the end of the functions.php file I added the function that will load your posts:

    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' => true,
            'post_type' => 'post',
            'posts_per_page' => $ppp,
            'cat' => 8,
            'paged'    => $page,
        );
    
        $loop = new WP_Query($args);
    
        $out = '';
    
        if ($loop -> have_posts()) :  while ($loop -> have_posts()) : $loop -> the_post();
            $out .= '<div class="small-12 large-4 columns">
                    <h1>'.get_the_title().'</h1>
                    <p>'.get_the_content().'</p>
             </div>';
    
        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');
    

    Here I've added paged key in the array, so that the loop can keep track on what page you are when you load your posts.

    If you've added your category in the loader, you'd add:

    $cat = (isset($_POST['cat'])) ? $_POST['cat'] : '';
    

    And instead of 8, you'd put $cat. This will be in the $_POST array, and you'll be able to use it in ajax.

    Last part is the ajax itself. In functions.js I put inside the $(document).ready(); enviroment

    var ppp = 3; // Post per page
    var cat = 8;
    var pageNumber = 1;
    
    
    function load_posts(){
        pageNumber++;
        var str = '&cat=' + cat + '&pageNumber=' + pageNumber + '&ppp=' + ppp + '&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();
    });
    

    Saved it, tested it, and it works :)

    Images as proof (don't mind the shoddy styling, it was done quickly). Also post content is gibberish xD

    enter image description here

    enter image description here

    enter image description here

    UPDATE

    For 'infinite load' instead on click event on the button (just make it invisible, with visibility: hidden;) you can try with

    $(window).on('scroll', function () {
        if ($(window).scrollTop() + $(window).height()  >= $(document).height() - 100) {
            load_posts();
        }
    });
    

    This should run the load_posts() function when you're 100px from the bottom of the page. In the case of the tutorial on my site you can add a check to see if the posts are loading (to prevent firing of the ajax twice), and you can fire it when the scroll reaches the top of the footer

    $(window).on('scroll', function(){
        if($('body').scrollTop()+$(window).height() > $('footer').offset().top){
            if(!($loader.hasClass('post_loading_loader') || $loader.hasClass('post_no_more_posts'))){
                    load_posts();
            }
        }
    });
    

    Now the only drawback in these cases is that you could never scroll to the value of $(document).height() - 100 or $('footer').offset().top for some reason. If that should happen, just increase the number where the scroll goes to.

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

    $(window).on('scroll', function () {
        console.log($(window).scrollTop() + $(window).height());
        console.log($(document).height() - 100);
        if ($(window).scrollTop() + $(window).height()  >= $(document).height() - 100) {
            load_posts();
        }
    });
    

    And just adjust accordingly ;)

    Hope this helps :) If you have any questions just ask.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog