移动端点击WooCommerce变体单选按钮页面滚顶问题排查
移动端点击商品尺寸/颜色的单选按钮时,页面会自动滚动到顶部,桌面端因处于页面顶部问题不明显。当前使用的单选按钮处理脚本如下:
jQuery(document).on('change', '.variation-radios input', function() { jQuery('.variation-radios input:checked').each(function(index, element) { var $el = jQuery(element); var thisName = $el.attr('name'); var thisVal = $el.attr('value'); jQuery('select[name="'+thisName+'"]').val(thisVal).trigger('change'); jQuery('[name=quantity]').val(1); }); }); jQuery(document).on('woocommerce_update_variation_values', function() { jQuery('.variation-radios input').each(function(index, element) { var $el = jQuery(element); var thisName = $el.attr('name'); var thisVal = $el.attr('value'); $el.removeAttr('disabled'); if(jQuery('select[name="'+thisName+'"] option[value="'+thisVal+'"]').is(':disabled')) { $el.prop('disabled', true); jQuery('[name=quantity]').val(1); } }); });
已尝试在脚本多处添加e.preventDefault()无效,且已将input放入label标签内,问题仍存在。该脚本此前可正常运行,希望通过代码排查并解决,不使用插件。
原因1:trigger('change')触发默认锚点跳转
触发select的change事件时,WooCommerce内部逻辑可能触发了锚点定位(比如隐式的表单提交或锚点跳转),导致页面回到顶部。
解决方法:修改触发change的方式,传入参数阻止默认行为,或直接在select的change事件中拦截:// 修改select触发change的代码 jQuery('select[name="'+thisName+'"]').val(thisVal).trigger('change', [{preventDefault: true}]); // 或者单独给变体select绑定阻止默认行为的事件 jQuery('select.variation_id').on('change', function(e) { e.preventDefault(); });原因2:页面重绘导致滚动偏移
切换商品变体时,WooCommerce会更新价格、库存等元素,页面布局重排可能导致浏览器自动滚动到顶部。
解决方法:记录当前滚动位置,变体更新完成后恢复:jQuery(document).on('change', '.variation-radios input', function() { // 记录滚动位置 const currentScroll = jQuery(window).scrollTop(); jQuery('.variation-radios input:checked').each(function(index, element) { var $el = jQuery(element); var thisName = $el.attr('name'); var thisVal = $el.attr('value'); jQuery('select[name="'+thisName+'"]').val(thisVal).trigger('change'); jQuery('[name=quantity]').val(1); }); // 恢复滚动位置 jQuery(window).scrollTop(currentScroll); });原因3:label或关联元素的锚点跳转
检查页面中是否存在绑定了单选按钮的label带有href="#"属性,点击时会触发锚点跳转至顶部。
解决方法:移除label的href="#",或在label的点击事件中阻止默认行为:jQuery('.variation-radios label').on('click', function(e) { e.preventDefault(); });原因4:WooCommerce版本更新的兼容性问题
脚本此前正常运行,可能是WooCommerce更新后内部事件逻辑变化,原脚本触发了额外的滚顶行为。
解决方法:调用WooCommerce官方的变体更新方法,替代模拟select的change事件:jQuery(document).on('change', '.variation-radios input', function() { const form = jQuery(this).closest('form.variations_form'); const selectedVariations = {}; jQuery('.variation-radios input:checked').each(function() { selectedVariations[jQuery(this).attr('name')] = jQuery(this).val(); }); // 调用官方方法更新变体 form.variationForm('update', selectedVariations); jQuery('[name=quantity]').val(1); });原因5:事件冒泡或浏览器默认行为
移动端浏览器对表单元素的点击可能有默认滚动逻辑,或其他插件干扰了事件流。
解决方法:在单选按钮的change事件中同时阻止默认行为和事件冒泡:jQuery(document).on('change', '.variation-radios input', function(e) { e.preventDefault(); e.stopPropagation(); // 原有处理代码... });
内容的提问来源于stack exchange,提问作者libertarian

