WooCommerce:产品归档页添加数量选择器后按钮消失修复
解决WooCommerce产品循环中多商品加购按钮消失问题
问题:在archive-products.php的产品循环中添加带数量选择的加购按钮后,单个商品加购功能正常,但添加多个商品时,循环中较早输出的商品对应的加购按钮会消失。
问题根源
- 原JS中直接绑定
click事件到静态元素,当按钮因AJAX操作动态更新后,事件绑定失效,导致按钮看似消失(实际是失去功能或被错误移除)。 adding_to_cart事件中移除所有added_to_cart链接,可能误操作其他商品的DOM结构,引发按钮异常。- 数量变化事件依赖固定DOM层级关系(
parent().next()),一旦页面结构变动就会失效。
修改后的完整代码
add_filter( 'woocommerce_loop_add_to_cart_link', function ( $html, $product ) { if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) { $class = implode( ' ', array_filter( array( 'button', 'product_type_' . $product->get_type(), $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '', $product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '', ) ) ); // 给form添加产品ID标识,方便JS精准定位 $html = sprintf( '%s%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s ct-cart-actions">%s</a>%s', '<form class="cart" data-product-id="' . esc_attr( $product->get_id() ) . '">', woocommerce_quantity_input( array(), $product, false ), esc_url( $product->add_to_cart_url() ), esc_attr( isset( $quantity ) ? $quantity : 1 ), esc_attr( $product->get_id() ), esc_attr( $product->get_sku() ), esc_attr( isset( $class ) ? $class : 'button' ), esc_html( $product->add_to_cart_text() ), '</form>' ); } return $html; }, 10, 2 ); add_action( 'wp_footer' , function (){ if( is_home() || is_front_page() || is_shop() || is_product_category() || is_product_tag() ) { ?> <script type='text/javascript'> jQuery( document ).ready( function( $ ) { // 用委托绑定数量变化事件,兼容动态DOM $( document ).on( 'change', '.quantity .qty', function() { var $qtyInput = $(this); // 向上找到当前产品的form容器,再精准定位加购按钮 var $addToCartBtn = $qtyInput.closest('.cart').find('.add_to_cart_button'); $addToCartBtn.attr( 'data-quantity', $qtyInput.val() ); }); // 委托绑定点击事件,确保动态生成的按钮也能触发 $( document ).on( 'click', '.add_to_cart_button.product_type_simple', function(e) { var $button = $(this); var qty = $button.closest('.cart').find('input.qty').val(); $button.data('quantity', qty); }); // 在adding_to_cart事件中,只移除当前操作对应的added_to_cart链接 $(document.body).on("adding_to_cart", function(event, $button) { $button.siblings('a.added_to_cart').remove(); }); }); </script> <?php } } );
关键改动说明
- PHP部分:给每个产品的
form标签添加data-product-id属性,让JS能精准定位当前产品的DOM元素,避免跨产品误操作。 - JS事件绑定:将所有元素绑定改为
$(document).on()委托模式,确保AJAX更新后新生成的按钮依然能触发事件。 - DOM定位优化:数量变化和点击事件中,用
closest('.cart')替代依赖固定层级的parent().next(),增强代码对DOM结构变动的兼容性。 - 精准移除元素:在
adding_to_cart事件中,只移除当前加购按钮的兄弟元素added_to_cart链接,不再影响其他产品的DOM结构。
内容的提问来源于stack exchange,提问作者SavPhill
相关产品推荐
相关产品推荐

