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

Shopify主题开发:默认选中首个可用商品变体对应单选按钮

问题根源

当前代码默认选中最后一个变体的核心原因是:在Liquid循环输出单选按钮时,给同组下所有单选按钮都添加了checked属性。对于相同name的单选按钮组,浏览器会默认选中最后一个携带checked属性的元素,和预期选中第一个可用变体的逻辑冲突。

修复方案
  • 移除单选按钮循环中硬编码的checked属性,不再在渲染阶段直接给所有选项加选中状态
  • 页面加载完成后,自动匹配第一个available: true的可用变体,选中其对应的所有选项值
  • 抽离价格更新逻辑为公共函数,页面初始化、用户切换选项时都可以调用,避免重复代码
  • 修正原逻辑中未判断变体可用状态的问题,避免选中缺货变体
修复后完整代码
<!-- 存储变体JSON数据 -->
<script id="variants" type="application/json">
    {{ product.variants | json }}
</script>

<script>
    var variantsArray = JSON.parse(document.getElementById("variants").text);
    // 抽离价格更新公共方法
    function updatePriceBySelectedOptions() {
        var checkedValues = document.querySelectorAll('input[type="radio"]:checked');
        var checkedArray = Array.from(checkedValues, radio => radio.value);
        
        for (let l = 0; l < variantsArray.length; l++) {
            // 匹配选中选项对应的变体
            if (JSON.stringify(checkedArray) == JSON.stringify(variantsArray[l].options)) {
                var priceString = variantsArray[l].price.toString();
                document.querySelector('.unit-price').textContent = `$${priceString.substr(0, priceString.length - 2)}`;
                // 可在这里扩展变体缺货判断、库存提示等逻辑
                break;
            }
        }
    }
</script>

<span class="unit-price">{{ price | money }}</span>
<div class="radios">
    {% for product_option in product.options_with_values %} 
        <h4 class="options-title">{{ product_option.name }}</h4>
        <div class="options-values">
            {% for value in product_option.values %}
                <!-- 移除所有硬编码的checked属性 -->
                <input type="radio" id="{{ value | handle }}" name="{{ product_option.name}}" value="{{ value }}">
                <label for="{{ value | handle }}">{{ value }}</label>  
            {% endfor %}
        </div>
        <div class="line"></div>
    {% endfor %}

    <script>
        var radioArray = document.querySelectorAll('input[type="radio"]');
        // 查找第一个可用变体,无可用变体时回退选中第一个变体
        var firstAvailableVariant = variantsArray.find(variant => variant.available) || variantsArray[0];
        
        // 页面初始化时选中第一个可用变体的对应选项
        firstAvailableVariant.options.forEach((optionValue, index) => {
            let optionName = document.querySelectorAll('.options-title')[index].textContent;
            let targetRadio = document.querySelector(`input[name="${optionName}"][value="${optionValue}"]`);
            if (targetRadio) targetRadio.checked = true;
        });

        // 初始化默认价格
        updatePriceBySelectedOptions();

        // 绑定选项切换事件
        for (let k = 0; k < radioArray.length; k++) {
            radioArray[k].addEventListener('change', updatePriceBySelectedOptions);
        }
    </script>
</div>
额外优化点
  • 给单选按钮的id加了handle过滤器,避免选项值带特殊字符(比如空格、斜杠)时id不合法导致label关联失效
  • 匹配到对应变体后加了break,找到目标后终止循环减少不必要的遍历
  • 增加无可用变体的兜底逻辑,避免页面加载后无单选按钮被选中的异常情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 00:21:40