JQuery触发change事件未激活目标函数问题求助
问题:滑块触发数字输入框change事件失败排查
需求场景
拖动范围滑块时,通过jQuery同步值到数字输入框,并触发其change事件,激活已定义的处理函数。
现有代码与现象
滑块监听代码(已验证选择器有效)
$('.summary').on('change', 'input[type="range"]', function(){ console.log('confimation'); $(this).parent().parent().find('.quantity input[type="number"]').val($(this).val()).attr('value', $(this).val()); $(this).closest('.bundled_item_button').find('input.bundled_qty').trigger('change'); });
期望触发的数字框处理函数
this.bind_bundled_item_event_handlers = function( bundled_item ) { console.log(bundled_item.$self); bundled_item.$self /** * Update totals upon changing quantities. */ .on( 'input change', 'input.bundled_qty', function( event ) { console.log('gevuurd'); var $input = $( this ), qty = parseFloat( $input.val() ), min = parseFloat( $input.attr( 'min' ) ), max = parseFloat( $input.attr( 'max' ) ); if ( wc_bundle_params.force_min_max_qty_input === 'yes' && 'change' === event.type ) { if ( min >= 0 && ( qty < min || isNaN( qty ) ) ) { qty = min; } if ( max > 0 && qty > max ) { qty = max; } $input.val( qty ); } // A zero quantity item is considered optional by NYP. if( bundled_item.is_nyp() && ! bundled_item.is_optional() && min === 0 ) { bundled_item.$nyp.data( 'optional_status', qty > 0 ? true : false ); } bundled_item.update_selection_title(); bundle.$bundle_data.trigger( 'woocommerce-product-bundle-update', [ bundled_item ] ); } ) }
异常现象
- 拖动滑块时,控制台无
gevuurd输出,目标函数未激活; - 新增全局监听代码后,控制台可正常输出
changed:
$('.cart').on('input change', 'input.bundled_qty', function(){ console.log('changed'); });
对应HTML结构
<div class="cart" data-title="Stokâlde fryske - 220gram" data-product_title="Stokâlde fryske - 220gram" data-visible="yes" data-optional_suffix="" data-optional="no" data-type="simple" data-bundled_item_id="4" data-custom_data="[]" data-product_id="181" data-bundle_id="168"> <div class="bundled_item_wrap"> <div class="bundled_item_cart_content"> <div class="bundled_item_cart_details"><span class="price"><span class="woocommerce-Price-amount amount"><span class="woocommerce-Price-currencySymbol">€</span>4.75</span> <span class="bundled_item_price_quantity">each</span></span> </div> <div class="bundled_item_after_cart_details bundled_item_button"> <div class="quantity"> <label class="screen-reader-text" for="quantity_6500736040691">Stokâlde fryske - 220gram aantal</label> <input type="number" id="quantity_6500736040691" class="input-text qty bundled_qty text" name="bundle_quantity_4" value="2" aria-label="Productaantal" size="4" min="0" max="4" step="1" placeholder="" inputmode="numeric" autocomplete="off"> </div> <div class="quantity"><input type="range" min="0" max="4" name="quantityslider"></div> </div> </div> </div>
问题根源
你绑定事件的方式是委托在bundled_item.$self上,但从日志和HTML结构可确认,bundled_item.$self本身就是input.bundled_qty元素。此时使用.on('input change', 'input.bundled_qty', ...)这种委托写法,相当于在这个input元素上监听其内部的input.bundled_qty子元素的事件——但该input内部并没有符合条件的子元素,所以事件永远不会被触发。
简言之:直接给元素绑定事件时,不需要添加后代选择器,委托写法仅适用于父元素监听子元素事件的场景。
解决方案
1. 修正数字框事件绑定代码
修改bind_bundled_item_event_handlers中的事件绑定逻辑,去掉后代选择器,直接绑定在bundled_item.$self上:
this.bind_bundled_item_event_handlers = function( bundled_item ) { console.log(bundled_item.$self); bundled_item.$self /** * Update totals upon changing quantities. */ .on( 'input change', function( event ) { // 移除第二个参数的后代选择器 console.log('gevuurd'); var $input = $( this ), qty = parseFloat( $input.val() ), min = parseFloat( $input.attr( 'min' ) ), max = parseFloat( $input.attr( 'max' ) ); if ( wc_bundle_params.force_min_max_qty_input === 'yes' && 'change' === event.type ) { if ( min >= 0 && ( qty < min || isNaN( qty ) ) ) { qty = min; } if ( max > 0 && qty > max ) { qty = max; } $input.val( qty ); } // A zero quantity item is considered optional by NYP. if( bundled_item.is_nyp() && ! bundled_item.is_optional() && min === 0 ) { bundled_item.$nyp.data( 'optional_status', qty > 0 ? true : false ); } bundled_item.update_selection_title(); bundle.$bundle_data.trigger( 'woocommerce-product-bundle-update', [ bundled_item ] ); } ) }
2. 简化滑块同步代码
滑块同步值的代码无需手动设置attr('value'),.val()已经同步了DOM的value属性(仅HTML源码的value不会更新,但不影响功能):
$('.summary').on('change', 'input[type="range"]', function(){ console.log('confimation'); const $numberInput = $(this).closest('.bundled_item_button').find('input.bundled_qty'); $numberInput.val($(this).val()); $numberInput.trigger('change'); });
内容的提问来源于stack exchange,提问作者NSsem
相关产品推荐
相关产品推荐

