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

修复WooCommerce变体图片无法删除及前端不显示问题

WooCommerce可变产品变体额外图片问题

近一周我编写自定义PHP与jQuery代码,为WooCommerce可变产品的每个变体添加额外图片上传功能,但遇到两个问题:

  • 无法删除已选中的图片
  • 上传的变体图片在前端页面完全不显示

参考LoicTheAztec的方案后,后台变体标签已能正常添加图片,但前端依然无展示效果,当前前端状态如图:
前端无图片展示状态

我使用的自定义代码

function custom_allow_multiple_variation_images($loop, $variation_data, $variation) {
    $variation_id = $variation->ID;
    $field_name = 'variation_image';
    $attachment_ids = get_post_meta($variation_id, $field_name, true);

    echo '<div class="upload_variation_image">';
    echo '<h4>Fotoğraf</h4>';
    echo '<input type="hidden" name="' . $field_name . '[' . $loop . ']" id="' . $field_name . '" class="upload_image" value="' . esc_attr(implode(',', (array) $attachment_ids)) . '" />';
    echo '<button class="upload_image_button button">Upload Image</button>';

    if ($attachment_ids) {
        $attachment_ids = explode(',', $attachment_ids);
        foreach ($attachment_ids as $attachment_id) {
            $image_src = wp_get_attachment_image_src($attachment_id, 'thumbnail');
            if ($image_src) {
                echo '<div class="uploaded_image_wrapper">';
                echo '<img src="' . esc_url($image_src[0]) . '" alt="Uploaded Image" />';
                echo '<span class="delete_variation_image" data-attachment_id="' . $attachment_id . '">Sil</span>';
                echo '</div>';
            }
        }
    }

    echo '</div>';
}

add_action('woocommerce_variation_options', 'custom_allow_multiple_variation_images', 10, 3);


function custom_save_variation_image($variation_id) {
    $field_name = 'variation_image';
    $attachment_ids = isset($_POST[$field_name]) ? array_map('absint', explode(',', wc_clean($_POST[ $field_name][0]))) : array();

    update_post_meta($variation_id, $field_name, implode(',', $attachment_ids));
}

add_action('woocommerce_save_product_variation', 'custom_save_variation_image', 10, 1);


add_action('woocommerce_save_product_variation', 'custom_save_variation_image', 10, 1);


function custom_variation_image_scripts() {
    ?>
    <script>
        jQuery(document).ready(function($) {

            function custom_add_variation_image($wrapper) {
                var file_frame;
                if (file_frame) {
                    file_frame.open();
                    return;
                }
                file_frame = wp.media.frames.file_frame = wp.media({
                    title: 'Variation Image Select',
                    button: {
                        text: 'Add Additional Image'
                    },
                    multiple: true
                });

                file_frame.on('select', function() {
                    var attachment_ids = [];
                    var selection = file_frame.state().get('selection');
                    selection.map(function(attachment) {
                        attachment = attachment.toJSON();
                        attachment_ids.push(attachment.id);
                    });
                    $wrapper.find('.upload_image').val(attachment_ids.join(','));
                    $wrapper.find('.uploaded_image_wrapper').remove();
                    attachment_ids.forEach(function(attachment_id) {
                        var image_url = wp.media.attachment(attachment_id).get('url');
                        $wrapper.append('<div class="uploaded_image_wrapper"><img src="' + image_url + '" alt="Uploaded Image" /><span class="delete_variation_image" data-attachment_id="' + attachment_id + '">Sil</span></div>');
                    });
                    $wrapper.find('.upload_image').trigger('change'); // Trigger change event when selecting a variation image
                });
                file_frame.open();
            }


            function custom_remove_variation_image($wrapper, attachment_id) {
                var attachment_ids = $wrapper.find('.upload_image').val().split(',');
                var index = attachment_ids.indexOf(attachment_id);
                if (index !== -1) {
                    attachment_ids.splice(index, 1);
                    $wrapper.find('.upload_image').val(attachment_ids.join(','));
                }
                $wrapper.find('.uploaded_image_wrapper[data-attachment_id="' + attachment_id + '"]').remove();
                $wrapper.find('.upload_image').trigger('change'); // Trigger change event when removing a variation image
            }


            function custom_detect_variation_changes() {
                $('form.cart').on('change', '.variation-control', function() {
                    $('.single_add_to_cart_button').prop('disabled', false);
                });

                // When a variation image changes, enable "Add to Cart" button
                $('form.cart').on('change', '.upload_image', function() {
                    $('.single_add_to_cart_button').prop('disabled', false);
                });
            }

            // Medya yükleyici olaylarını ekle
            $(document).on('click', '.upload_image_button', function(e) {
                e.preventDefault();
                custom_add_variation_image($(this).closest('.upload_variation_image'));
            });

            $(document).on('click', '.delete_variation_image', function() {
                var attachment_id = $(this).data('attachment_id');
                custom_remove_variation_image($(this).closest('.upload_variation_image'), attachment_id);
            });


            custom_detect_variation_changes();
        });
    </script>
    <style>
        .uploaded_image_wrapper {
            margin: 10px 0;
            display: inline-block;
        }

        .uploaded_image_wrapper img {
            max-width: 100px;
            height: auto;
            margin-right: 10px;
        }

        .delete_variation_image {
            cursor: pointer;
            color: #a00;
        }
    </style>
    <?php
}

add_action( 'admin_footer', 'custom_variation_image_scripts' );

问题修复方案

1. 修复后台图片删除功能

你的删除函数中,尝试通过data-attachment_id选择容器,但后台渲染的.uploaded_image_wrapper未携带该属性,导致无法正确移除元素。同时ID类型不匹配也会导致数组索引查找失败,修改如下:

第一步:修改PHP渲染代码
给图片容器添加data-attachment_id属性:

echo '<div class="uploaded_image_wrapper" data-attachment_id="' . $attachment_id . '">';
echo '<img src="' . esc_url($image_src[0]) . '" alt="Uploaded Image" />';
echo '<span class="delete_variation_image" data-attachment_id="' . $attachment_id . '">Sil</span>';
echo '</div>';

第二步:修改JS删除函数
确保ID类型匹配,并正确选择容器:

function custom_remove_variation_image($wrapper, attachment_id) {
    var attachment_ids = $wrapper.find('.upload_image').val().split(',');
    var index = attachment_ids.indexOf(attachment_id.toString()); // 统一为字符串类型匹配
    if (index !== -1) {
        attachment_ids.splice(index, 1);
        $wrapper.find('.upload_image').val(attachment_ids.join(','));
    }
    $wrapper.find('.uploaded_image_wrapper[data-attachment_id="' + attachment_id + '"]').remove();
    $wrapper.find('.upload_image').trigger('change');
}

第三步:删除重复钩子
代码中重复添加了保存钩子,删除其中一行:

// 删除此行重复代码
// add_action('woocommerce_save_product_variation', 'custom_save_variation_image', 10, 1);

2. 前端展示变体额外图片

添加前端监听与AJAX获取代码,实现变体切换时加载对应额外图片:

// 前端变体图片展示脚本
function custom_variation_frontend_scripts() {
    if (is_product() && wc_get_product()->is_type('variable')) {
        ?>
        <script>
            jQuery(document).ready(function($) {
                // 变体选中时加载额外图片
                $('form.variations_form').on('show_variation', function(event, variation) {
                    $.ajax({
                        url: wc_add_to_cart_params.ajax_url,
                        type: 'POST',
                        data: {
                            action: 'get_variation_extra_images',
                            variation_id: variation.variation_id
                        },
                        success: function(response) {
                            $('.variation-extra-images').remove();
                            if (response.success && response.data.images.length > 0) {
                                var $container = $('<div class="variation-extra-images" style="margin-top:15px;"></div>');
                                response.data.images.forEach(function(img) {
                                    $container.append('<img src="' + img.src + '" alt="变体额外图片" style="max-width:200px; height:auto; margin-right:10px; margin-bottom:10px;" />');
                                });
                                $('.woocommerce-product-gallery').after($container);
                            }
                        }
                    });
                });

                // 取消变体选择时清空图片
                $('form.variations_form').on('hide_variation', function() {
                    $('.variation-extra-images').remove();
                });
            });
        </script>
        <?php
    }
}
add_action('wp_footer', 'custom_variation_frontend_scripts');

// AJAX接口:获取变体额外图片
function get_variation_extra_images() {
    if (!isset($_POST['variation_id']) || !is_numeric($_POST['variation_id'])) {
        wp_send_json_error('无效的变体ID');
    }

    $variation_id = absint($_POST['variation_id']);
    $attachment_ids = get_post_meta($variation_id, 'variation_image', true);
    $images = array();

    if ($attachment_ids) {
        foreach(explode(',', $attachment_ids) as $id) {
            $src = wp_get_attachment_image_src($id, 'medium')[0];
            if ($src) $images[] = array('src' => $src);
        }
    }

    wp_send_json_success(array('images' => $images));
}
add_action('wp_ajax_get_variation_extra_images', 'get_variation_extra_images');
add_action('wp_ajax_nopriv_get_variation_extra_images', 'get_variation_extra_images');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:39:53