WordPress中同一页面多个自定义短代码实现独立AJAX分页的问题求助
WordPress中同一页面多个自定义短代码实现独立AJAX分页的问题求助
我完全懂你现在的困扰——同一页面放多个[multi-atts]短代码(比如[multi-atts category="apple,lg"]和[multi-atts category="nokia"]),点击分页按钮时,所有短代码的内容都会被统一更新,没法各自独立加载对应分类的分页内容对吧?
问题的核心在于当前代码没有给每个短代码实例分配唯一标识:
- 所有区块共用同一个
.section-mobile-listing类,JS选择器会选中所有匹配元素,更新时会替换所有区块; - 隐藏输入框用了ID选择器
#att,同一页面多个相同ID会导致JS只能获取第一个的值; - AJAX请求没有传递实例专属的标识/参数,后台无法区分要处理哪个短代码的请求。
下面是具体的修复方案,一步步来:
1. 给每个短代码实例生成唯一ID
在functions.php的multi_atts短代码函数里,添加一个唯一标识,用来区分每个实例:
function multi_atts( $atts ){ ob_start(); $atts = shortcode_atts( array( 'category' => '', ), $atts ); // 生成唯一实例ID,用分类名+随机字符串确保唯一性 $instance_id = 'mobile-listing-' . md5($atts['category'] . uniqid()); include(locate_template('template-parts/multi-atts/multi_atts.php', false, false)); return ob_get_clean(); }
2. 修改模板文件,绑定唯一标识到区块
在template-parts/multi-atts/multi_atts.php里,把唯一ID应用到section区块和分页容器,同时把分类信息存在section的data属性里(替代原来的隐藏输入框,避免ID冲突):
<?php // 处理分页逻辑(保持你原来的代码不变) if ( get_query_var( 'paged' ) ) { $paged = get_query_var( 'paged' ); } else if ( get_query_var( 'page' ) ) { $paged = get_query_var( 'page' ); } else if ( get_query_var( 'pageno' ) ) { $paged = get_query_var( 'pageno' ); } else if( isset($_POST["page"]) ) { $paged = $_POST["page"]; } else { $paged = 1; } // 处理分类参数(保持你原来的代码不变) $current_cat = array(); if(isset($atts['category']) && !empty($atts['category'])){ $current_cat = explode(",", $atts['category']); } else { $current_brand_slug = get_query_var( 'brand' ) ? get_query_var( 'brand' ) : (isset($_POST["brand"]) ? $_POST["brand"] : null); $current_cat = explode(",", $current_brand_slug); } // WP_Query参数(保持你原来的代码不变) $args = array( 'post_type' => 'mobiles', 'post_status' => 'publish', 'posts_per_page' => 4, 'paged' => $paged, 'suppress_filter' => false, 'orderby' => 'date', 'order' => 'ASC', 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'brand', 'field' => 'slug', 'terms' => $current_cat, ) ), ); $cl_posts = new WP_Query( $args ); // 确保instance_id存在(AJAX请求时会传递过来) $instance_id = isset($_POST['instance_id']) ? sanitize_text_field($_POST['instance_id']) : (isset($instance_id) ? $instance_id : 'mobile-listing-' . uniqid()); ?> <?php if($cl_posts->have_posts() ) { ?> <!-- 用唯一ID作为section的ID,同时保留类;分类信息存在data-category里 --> <section id="<?php echo esc_attr($instance_id); ?>" class="section-mobile-listing" data-action="mobile_filter" data-base-url="<?php echo esc_attr(get_post_field( 'post_name')); ?>" data-category="<?php echo esc_attr($atts['category']); ?>"> <?php while ( $cl_posts->have_posts() ) { $cl_posts->the_post(); ?> <h4><?php the_title(); ?></h4> <?php } wp_reset_postdata(); ?> </section> <?php } else { ?> <div id="<?php echo esc_attr($instance_id); ?>" class="section-mobile-listing"> <div class="col-12"> <h5 class="no-posts-found">No post found.</h5> </div> </div> <?php } wp_reset_postdata(); ?> <?php if ( $cl_posts->have_posts() ) { ?> <?php global $wp_append_pageno; $wp_append_pageno = true; ?> <!-- 分页容器绑定对应的实例ID,方便JS关联 --> <div class="section-pagination cst-ajax-listing" data-instance="<?php echo esc_attr($instance_id); ?>"> <?php wp_pagenavi( array( 'query' => $cl_posts, 'format' => '?page=%#%', ) ); ?> </div> <?php } ?>
3. 修改JS代码,实现独立分页逻辑
更新JS,让每个分页按钮只对应自己所属的短代码区块,传递正确的分类和实例参数:
// Ajax分页点击事件 jQuery(document).on("click", ".cst-ajax-listing .wp-pagenavi a", function (e) { e.preventDefault(); // 获取当前分页所属的实例ID const instanceId = jQuery(this).closest('.cst-ajax-listing').data('instance'); // 找到对应的section区块 const sectionWrapper = jQuery('#' + instanceId); // 解析分页页码 const url = new URL(jQuery(this).attr("href")); const urlArgs = new URLSearchParams(url.search); const nextPage = urlArgs.get("pageno") ? urlArgs.get("pageno") : 1; // 调用更新函数,传递页码和实例ID updateMobileListing(nextPage, instanceId); }); let ajaxTimeout; function updateMobileListing(page, instanceId) { clearTimeout(ajaxTimeout); const sectionWrapper = jQuery('#' + instanceId); const currentPage = page !== "undefined" ? page : 1; // 从section的data属性获取分类参数 const category = sectionWrapper.data('category'); ajaxTimeout = setTimeout(function () { jQuery.ajax({ type: "post", url: app['admin_url'], data: { action: sectionWrapper.attr("data-action"), pageno: currentPage, page: currentPage, brand: category, instance_id: instanceId // 传递实例ID,确保AJAX返回的区块ID和原来一致 }, beforeSend: function () { // 可选:给当前区块添加加载状态 sectionWrapper.addClass('loading'); }, success: function (response) { // 只替换当前实例的section区块 sectionWrapper.replaceWith(response); }, complete: function () { // 移除加载状态 sectionWrapper.removeClass('loading'); } }); }, 700); }
4. 调整AJAX处理函数(确保兼容性)
在functions.php的mobile_filter函数里,接收AJAX传递的实例ID和分类参数,确保返回的内容正确绑定到原实例:
add_action('wp_ajax_nopriv_mobile_filter', 'mobile_filter'); add_action('wp_ajax_mobile_filter', 'mobile_filter'); function mobile_filter() { // 从AJAX请求中获取分类和实例ID参数 $atts = array( 'category' => isset($_POST['brand']) ? sanitize_text_field($_POST['brand']) : '' ); $instance_id = isset($_POST['instance_id']) ? sanitize_text_field($_POST['instance_id']) : 'mobile-listing-' . uniqid(); include(locate_template('template-parts/multi-atts/multi_atts.php', false, false)); wp_die(); }
这样修改后,每个[multi-atts]短代码实例都会有自己的唯一标识,点击分页按钮时,只会更新对应分类的内容,多个短代码在同一页面就能独立工作了。
备注:内容来源于stack exchange,提问作者Pankaj
相关产品推荐
相关产品推荐

