WooCommerce商品归档页动态数据问题:替换加入购物车为询价按钮
解决WooCommerce归档页询价弹窗无法获取对应产品数据的问题
问题说明
需要将WooCommerce商品归档页的「加入购物车」按钮替换为「询价」按钮,点击后通过Elementor弹窗展示对应产品的图片、标题等动态数据。当前单个产品页弹窗正常,但归档页弹窗仅显示第一个产品的数据,现有代码无法正确传递对应产品的信息。
问题原因
woocommerce_after_shop_loop_item钩子默认不会主动传递$product对象,导致原代码无法正确获取当前循环产品的信息。- Elementor弹窗默认不会自动读取归档页中每个产品的动态数据,需要通过JavaScript手动将产品数据填充到表单字段中。
解决方案
1. 修正PHP代码:正确获取产品数据并添加询价按钮
替换原有的PHP代码,确保能正确获取归档页每个产品的信息,并在按钮上存储完整的产品数据(包括图片URL):
// 移除归档页的加入购物车按钮 add_action('woocommerce_before_shop_loop_item_title', 'remove_archive_add_to_cart', 10); function remove_archive_add_to_cart() { remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10); } // 添加询价按钮到归档页产品项 add_action('woocommerce_after_shop_loop_item', 'add_archive_enquiry_button', 11); function add_archive_enquiry_button() { global $product; if (!is_a($product, 'WC_Product')) return; $product_id = $product->get_id(); $product_title = $product->get_title(); $product_desc = wp_strip_all_tags($product->get_short_description()); $product_img = wp_get_attachment_url($product->get_image_id()); $popup_url = '#elementor-action%3Aaction%3Dpopup%3Aopen%26settings%3DeyJpZCI6IjM4MiIsInRvdGdsZSI6ZmFsc2V9'; echo sprintf( '<a href="%s" class="button get_price_button" data-product-id="%s" data-product-title="%s" data-product-desc="%s" data-product-img="%s" data-elementor-open-lightbox="yes" data-elementor-lightbox-id="382">询价</a>', esc_url($popup_url), esc_attr($product_id), esc_attr($product_title), esc_attr($product_desc), esc_url($product_img) ); }
2. 添加JavaScript:传递产品数据到Elementor弹窗
将以下代码添加到子主题的functions.php中,或者通过Elementor的自定义JS功能添加:
add_action('wp_footer', 'enquiry_popup_product_data', 99); function enquiry_popup_product_data() { if (!is_shop() && !is_product_category() && !is_product_tag()) return; ?> <script> document.addEventListener('DOMContentLoaded', function() { // 监听所有询价按钮的点击事件 document.querySelectorAll('.get_price_button').forEach(button => { button.addEventListener('click', function(e) { // 获取当前按钮存储的产品数据 const productId = this.dataset.productId; const productTitle = this.dataset.productTitle; const productDesc = this.dataset.productDesc; const productImg = this.dataset.productImg; // 等待弹窗加载完成后填充数据 setTimeout(() => { // 替换弹窗中的产品标题(需将#product-title替换为你Elementor字段的ID) const titleField = document.querySelector('#product-title'); if (titleField) titleField.textContent = productTitle; // 替换弹窗中的产品描述(需将#product-desc替换为你Elementor字段的ID) const descField = document.querySelector('#product-desc'); if (descField) descField.textContent = productDesc; // 替换弹窗中的产品图片(需将#product-img替换为你Elementor图片元素的ID) const imgField = document.querySelector('#product-img'); if (imgField) imgField.src = productImg; // 如果需要将产品ID隐藏到表单字段中(比如隐藏输入框) const idField = document.querySelector('#product-id-input'); if (idField) idField.value = productId; }, 300); }); }); }); </script> <?php }
3. Elementor弹窗表单设置
- 打开你的Elementor弹窗模板,给需要展示产品数据的元素添加自定义ID:
- 产品标题文本框:设置ID为
product-title - 产品描述文本框:设置ID为
product-desc - 产品图片元素:设置ID为
product-img - 如果需要在表单中提交产品ID,添加一个隐藏输入框,设置ID为
product-id-input
- 产品标题文本框:设置ID为
注意事项
- 确保Elementor弹窗的ID(代码中的
382)与你实际的弹窗ID一致,可在Elementor弹窗设置中查看。 - 若产品描述包含特殊字符,
wp_strip_all_tags会清理HTML标签,避免弹窗出现格式问题。 - 调整
setTimeout的时间(300ms),如果弹窗加载较慢,可适当延长时间确保元素已渲染。
内容的提问来源于stack exchange,提问作者ajax
相关产品推荐
相关产品推荐

