WordPress自定义文章类型Ajax加载更多:无内容时自动隐藏按钮
解决方案:提前判断是否有更多文章,初始自动隐藏按钮
这个需求很常见——我们需要让前端在页面加载完成时就知道是否还有更多内容,而不是等用户点击按钮后才发现没东西可加载。核心思路是让后端把总可加载页数传递给前端,前端通过这个参数提前判断是否需要显示按钮。
第一步:修改后端AJAX回调,返回总页数和文章内容
原来的后端直接输出HTML内容,现在我们要把文章内容和总页数打包成JSON返回,这样前端能拿到关键的分页信息:
add_action('wp_ajax_load_posts_by_ajax', 'load_posts_by_ajax_callback'); add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_posts_by_ajax_callback'); function load_posts_by_ajax_callback() { check_ajax_referer('load_more_posts', 'security'); $date_now = date('Y-m-d H:i:s'); $paged = $_POST['page']; $args = array( 'posts_per_page' => 2, 'post_type' => 'termin', 'meta_query' => array( 'key' => 'end_date', 'compare' => '>=', 'value' => $date_now, 'type' => 'DATETIME' ), 'orderby' => 'end_date', 'order' => 'ASC', 'meta_type' => 'DATE', 'post_status' => 'publish', 'paged' => $paged, ); $my_posts = new WP_Query( $args ); // 捕获模板输出的HTML内容 $html_content = ''; if ( $my_posts->have_posts() ) : while ( $my_posts->have_posts() ) : $my_posts->the_post(); ob_start(); include(get_template_directory().'/termine-ajax.php'); $html_content .= ob_get_clean(); endwhile; endif; // 返回JSON格式数据,包含内容和总页数 wp_send_json(array( 'html' => $html_content, 'max_pages' => $my_posts->max_num_pages )); wp_die(); }
这里用ob_start()和ob_get_clean()来捕获模板的输出内容,再结合WP_Query自带的max_num_pages(总可加载页数),用wp_send_json()统一返回给前端。
第二步:修改前端JS,初始化时判断按钮状态
我们需要先拿到总页数,然后在页面加载完成后立刻判断:如果当前要加载的页码(初始是2)已经大于等于总页数,直接隐藏按钮。每次请求后也要更新这个判断:
// 注意:我们用WordPress官方推荐的wp_localize_script传递参数,避免JS里直接写PHP // 先在functions.php里配置参数,下面会讲这个步骤 jQuery(function($) { var ajaxurl = ajax_params.ajaxurl; var currentPage = 2; var totalPages = ajax_params.max_pages; $('.loading').hide(); // 页面加载完成后立刻判断:没有更多内容就隐藏按钮 if (currentPage > totalPages) { $('.loadmore').hide(); } $('body').on('click', '.loadmore', function(e) { e.preventDefault(); $('.loadmore').hide(); $('.loading').show(); var data = { 'action': 'load_posts_by_ajax', 'page': currentPage, 'security': ajax_params.security }; $.post(ajaxurl, data, function(response) { $('.loading').hide(); if(response.html.trim() != '') { $('.ajax-posts').append(response.html); currentPage++; // 加载后再次判断:还有内容才显示按钮 if (currentPage <= totalPages) { $('.loadmore').show(); } else { $(".ajax-posts").append("<p class='no-more'>No More Records Found</p>"); } } else { $(".ajax-posts").append("<p class='no-more'>No More Records Found</p>"); } }, 'json'); // 指定接收JSON格式数据 }); });
关键补充:提前把总页数传递到前端
上面的ajax_params.max_pages需要我们在页面初始化时就获取,所以要在主题的functions.php里,通过wp_localize_script把参数传递给JS:
function enqueue_theme_assets() { // 注册并加载你的主题脚本 wp_enqueue_script('theme-ajax-script', get_template_directory_uri() . '/js/ajax-load-more.js', array('jquery'), '1.0', true); // 提前查询一次,获取总页数 $date_now = date('Y-m-d H:i:s'); $query_args = array( 'posts_per_page' => 2, 'post_type' => 'termin', 'meta_query' => array( 'key' => 'end_date', 'compare' => '>=', 'value' => $date_now, 'type' => 'DATETIME' ), 'orderby' => 'end_date', 'order' => 'ASC', 'meta_type' => 'DATE', 'post_status' => 'publish', ); $posts_query = new WP_Query( $query_args ); $total_pages = $posts_query->max_num_pages; // 把参数传递到JS wp_localize_script('theme-ajax-script', 'ajax_params', array( 'ajaxurl' => admin_url('admin-ajax.php'), 'security' => wp_create_nonce("load_more_posts"), 'max_pages' => $total_pages )); wp_reset_postdata(); } add_action('wp_enqueue_scripts', 'enqueue_theme_assets');
这样页面加载时,JS就能直接拿到总页数,不用等用户点击按钮才知道有没有内容,完美实现初始自动隐藏按钮的效果。
为什么原来的逻辑达不到需求?
原来的后端在没有文章时返回空内容,前端只有在用户点击按钮发起请求后才会知道没有内容,所以只能在点击后隐藏按钮。现在通过提前获取总页数,前端可以在页面初始化阶段就完成判断,彻底解决这个问题。
内容的提问来源于stack exchange,提问作者herrfischer
相关产品推荐
相关产品推荐

