You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce AJAX搜索加购:首次点击按钮页面刷新问题求助

问题

这是一款支持分类筛选的WooCommerce产品AJAX实时搜索功能,当前存在异常:首次点击“加入购物车”按钮时,页面会刷新且不显示“查看购物车”选项;第二次点击则可正常显示“查看购物车”且无页面刷新。需要修复仅首次点击出现的页面加载问题。


现有代码

PHP代码

function perform_product_search() {
    $searchQuery = isset($_POST['search_query']) ? sanitize_text_field($_POST['search_query']) : '';
    $categoryFilter = isset($_POST['category_filter']) ? $_POST['category_filter'] : array();

    $args = array(
        'post_type' => 'product',
        'post_status' => 'publish',
        'posts_per_page' => -1, // 显示所有产品
        's' => $searchQuery,
    );

    if (!empty($categoryFilter)) {
        $args['tax_query'] = array(
            array(
                'taxonomy' => 'product_cat',
                'field' => 'term_id',
                'terms' => $categoryFilter,
                'operator' => 'IN',
            ),
        );
    }

    $loop = new WP_Query($args);
    $count = 0;

    ob_start(); // 启动输出缓冲

    if ($loop->have_posts()) {
        echo '<div class="product-row">'; // 开始产品行
        while ($loop->have_posts()) : $loop->the_post();
            if ($count % 4 === 0 && $count > 0) {
                echo '</div><div class="product-row">'; // 每4个产品后换行
            }
            echo '<div class="col-md-3">'; // 添加列容器
            wc_get_template_part('content', 'product');
            echo '</div>'; // 关闭列容器
            $count++;
        endwhile;
        echo '</div>'; // 关闭最后一行
    } else {
        echo __('未找到产品');
    }

    wp_reset_postdata();

    $output = ob_get_clean(); // 获取缓冲内容

    // 无搜索条件时显示所有产品
    if (empty($searchQuery) && empty($categoryFilter)) {
        $args_all = array(
            'post_type' => 'product',
            'post_status' => 'publish',
            'posts_per_page' => -1,
        );

        $loop_all = new WP_Query($args_all);
        $count_all = 0;

        ob_start();

        if ($loop_all->have_posts()) {
            echo '<div class="product-row">';
            while ($loop_all->have_posts()) : $loop_all->the_post();
                if ($count_all % 4 === 0 && $count_all > 0) {
                    echo '</div><div class="product-row">';
                }
                echo '<div class="col-md-3">';
                wc_get_template_part('content', 'product');
                echo '</div>';
                $count_all++;
            endwhile;
            echo '</div>';
        } else {
            echo __('未找到产品');
        }

        wp_reset_postdata();

        $output_all = ob_get_clean();
        if (empty($output)) {
            $output = $output_all;
        }
    }

    echo $output;

    die();
}


add_action('wp_ajax_perform_product_search', 'perform_product_search');
add_action('wp_ajax_nopriv_perform_product_search', 'perform_product_search');

// AJAX加入购物车
function add_to_cart() {
    $product_id = isset($_POST['product_id']) ? absint($_POST['product_id']) : 0;
    $quantity = isset($_POST['quantity']) ? absint($_POST['quantity']) : 1;

    if ($product_id > 0) {
        WC()->cart->add_to_cart($product_id, $quantity);

        // 返回更新后的购物车片段
        ob_start();
        woocommerce_mini_cart();
        $mini_cart = ob_get_clean();

        wp_send_json_success(array(
            'fragments' => apply_filters('woocommerce_add_to_cart_fragments', array(
                '.widget_shopping_cart_content' => $mini_cart,
            )),
            'cart_url' => wc_get_cart_url() // 新增购物车URL返回字段
        ));
    }

    wp_send_json_error();
}
add_action('wp_ajax_add_to_cart', 'add_to_cart');
add_action('wp_ajax_nopriv_add_to_cart', 'add_to_cart');


// 短代码实现
function realtime_product_search_shortcode() {
    ob_start();

    // 获取产品分类
    $categories = get_terms(array(
        'taxonomy' => 'product_cat',
        'hide_empty' => true,
    ));?>
    <div class="realtime-product-search">
        <input type="text" id="product-search" placeholder="搜索产品..." />
        <div id="category-filter">
            <h4>按分类筛选:</h4>
            <label>
                <input type="checkbox" name="category_filter[]" value="" /> 所有分类
            </label>
            <?php foreach ($categories as $category) : ?>
                <label>
                    <input type="checkbox" name="category_filter[]" value="<?php echo $category->term_id; ?>" />
                    <?php echo $category->name; ?>
                </label>
            <?php endforeach; ?>
        </div>
        <div id="search-results"></div>
    </div>
    <?php return ob_get_clean();
}
add_shortcode('realtime_product_search', 'realtime_product_search_shortcode');

JS代码

(function($){
$(document).ready(function ($) {
    var typingTimer;
    var doneTypingInterval = 500; // 输入延迟时间(毫秒)

    function performProductSearch() {
        clearTimeout(typingTimer);

        typingTimer = setTimeout(function() {
            var searchQuery = $('#product-search').val();
            var categoryFilter = [];

            $('input[name="category_filter[]"]:checked').each(function() {
                var value = $(this).val();
                if (value !== '') {
                    categoryFilter.push(value);
                }
            });

            $.ajax({
                url: realtime_product_search_ajax.ajax_url,
                type: 'POST',
                data: {
                    action: 'perform_product_search',
                    search_query: searchQuery,
                    category_filter: categoryFilter
                },
                beforeSend: function() {
                    $('#search-results').html('搜索中...');
                },
                success: function(response) {
                    $('#search-results').html(response);
                }
            });
        }, doneTypingInterval);
    }

    // 输入变化时触发搜索
    $('#product-search, input[name="category_filter[]"]').on('change keyup', function() {
        performProductSearch();
    });

    // 加入购物车功能
    $(document).on('submit', '.add-to-cart-form', function(e) {
        e.preventDefault(); // 优先阻止表单默认提交行为

        var form = $(this);
        var product_id = form.find('.product-id').val();
        var quantity = form.find('.quantity').val();

        // 移除已存在的查看购物车按钮,避免重复添加
        form.next('.button.wc-forward').remove();

        $.ajax({
            url: realtime_product_search_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'add_to_cart',
                product_id: product_id,
                quantity: quantity
            },
            beforeSend: function() {
                // 可添加加载动画
            },
            success: function(response) {
                if (response.success) {
                    // 更新购物车片段
                    $(document.body).trigger('wc_fragment_refresh');

                    // 提示添加成功
                    alert('产品已加入购物车');

                    // 显示查看购物车按钮
                    var viewCartUrl = response.data.cart_url;
                    var viewCartButton = '<a href="' + viewCartUrl + '" class="button wc-forward">查看购物车</a>';
                    form.after(viewCartButton);
                }
            },
            error: function() {
                alert('加入购物车失败,请重试');
            }
        });
    });
});

})(jQuery);

修复方案

1. 核心问题分析

首次点击刷新的原因有两个:

  • PHP端未返回购物车URL,JS尝试获取不存在的response.fragments.cart_url导致代码报错,无法完全阻止表单默认提交;
  • 未处理重复添加按钮的逻辑,首次AJAX成功后按钮未正确生成。

2. 具体修复步骤

步骤1:PHP端补充购物车URL返回

在add_to_cart函数的成功响应中添加cart_url字段,使用WooCommerce内置函数wc_get_cart_url()获取购物车地址:

wp_send_json_success(array(
    'fragments' => apply_filters('woocommerce_add_to_cart_fragments', array(
        '.widget_shopping_cart_content' => $mini_cart,
    )),
    'cart_url' => wc_get_cart_url() // 新增此行
));

步骤2:JS端修正逻辑

  • 确保e.preventDefault()在函数最开始执行,彻底阻止表单默认提交;
  • 修正购物车URL的获取路径为response.data.cart_url;
  • 添加移除已有按钮的逻辑,避免重复生成;
  • 增加AJAX错误处理,提升用户体验。

步骤3:检查产品表单字段

确认AJAX加载的产品表单中包含.product-id隐藏字段,若缺失需在WooCommerce产品模板中添加:

<input type="hidden" class="product-id" value="<?php echo get_the_ID(); ?>" />

内容的提问来源于stack exchange,提问作者SavPhill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 06:54:58