Wordpress中Alpine.js+AJAX加载更多按钮显隐异常排查
问题修复方案
1. 修复AJAX接口,返回总文章数
你的PHP AJAX函数未返回total字段,导致前端无法获取正确的总文章数。修改filterPosts函数,在响应中添加总文章数字段:
<?php // the ajax function add_action('wp_ajax_filterPosts', 'filterPosts'); add_action('wp_ajax_nopriv_filterPosts', 'filterPosts'); function filterPosts() { $response = [ 'posts' => "", 'total' => 0, // 新增默认total值 ]; $all_args = array( 'posts_per_page' => -1, 'post_status' => 'publish', ); $filter_args = array( 'post_status' => 'publish', ); if ($_POST['limit']) { $filter_args['posts_per_page'] = max (0, (int) $_POST['limit']); } if (isset($_POST['offset'])) { $filter_args['offset'] = max (0, (int)$_POST['offset']); } if ($_POST['post_type_js']) { $filter_args['post_type'] = $_POST['post_type_js']; $all_args['post_type'] = $_POST['post_type_js']; // 统计总数量时同步带上文章类型 } if ($_POST['category']) { $filter_args['cat'] = $_POST['category']; $all_args['cat'] = $_POST['category']; } $filter_query = new WP_Query($filter_args); $all_query = new WP_Query($all_args); // 赋值当前筛选条件下的总文章数 $response['total'] = $all_query->found_posts; if ($filter_query->have_posts()) : while ($filter_query->have_posts()) : $filter_query->the_post(); $response['posts'] .= load_template_part('/template-parts/posts-filter/single-post'); endwhile; wp_reset_postdata(); endif; echo json_encode($response); die(); }
2. 修复前端getTotal()函数,传递筛选参数
当前getTotal()仅传递了action参数,未携带post_type_js和category,导致统计的是全站所有文章,而非当前筛选条件下的总数量。同时切换分类时需重新调用getTotal()更新总数:
<script> Alpine.data("filterPosts", (adminURL) => ({ posts: "", limit: 6, total: 0, category: 0, post_type_js: post_id, showDefault: true, showFiltered: false, offset: 0, filterPosts(id) { this.showDefault = false; this.showFiltered = true; this.category = id; this.offset = 0; this.fetchPosts(); this.getTotal(); // 切换分类后重新获取总数量 }, loadMore() { this.loadingMore = true; this.offset += 6; this.showFiltered = true; this.fetchPosts(true); }, fetchPosts(append = false) { var formData = new FormData(); formData.append("action", "filterPosts"); formData.append("limit", this.limit); formData.append("post_type_js", this.post_type_js); formData.append("offset", this.offset); if (this.category) { formData.append("category", this.category); } fetch(adminURL, { method: "POST", body: formData, }) .then((res) => res.json()) .then((res) => { if (append) { this.posts = this.posts.concat(res.posts); } else { this.posts = res.posts; } this.loading = false; // 可选:直接在fetchPosts时同步更新total,减少一次请求 // this.total = res.total; }); }, getTotal() { var formData = new FormData(); formData.append("action", "filterPosts"); formData.append("post_type_js", this.post_type_js); // 传递文章类型参数 if (this.category) { formData.append("category", this.category); // 传递分类ID参数 } fetch(adminURL, { method: "POST", body: formData, }) .then((res) => res.json()) .then((res) => { this.total = res.total; }); }, init() { this.getTotal(); } })); </script>
3. 优化按钮显示逻辑
当前x-show="total > (limit + offset)"逻辑正确,但可添加初始状态判断,避免异步请求未完成时按钮闪烁:
<!-- Load More Posts --> <div @click="loadMore()" x-show="total > 0 && total > (offset + limit)" class="text-center mt-12 pt-5"> <button class=""> Load More </button> </div>
额外优化:减少AJAX请求
可以在fetchPosts请求时直接同步更新total,无需单独调用getTotal(),节省一次请求:
在前端fetchPosts的then回调中添加:
this.total = res.total;
之后可以删除getTotal()函数,并在init()中直接调用fetchPosts()(如果需要初始加载筛选后的内容)。
内容的提问来源于stack exchange,提问作者Beep
相关产品推荐
相关产品推荐

