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 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题