Shopify集合页:将下拉式变体选择器改为按钮式
Shopify集合页变体选择器(下拉转按钮式)改造方案
核心改造思路
把原有的<select>下拉组件替换为按钮组,通过隐藏的<input>字段传递选中的变体ID,同时用JavaScript处理按钮的选中状态切换、售罄变体的禁用逻辑,保证和原有加购功能完全兼容。
完整修改代码
直接替换原代码中变体选择器相关部分,以下是改造后的完整代码:
{% unless sold_out %} <form action="/cart/add" method="post" enctype="multipart/form-data" id="product-form-{{ product.id }}" class="product-form"> <div class="add-to-cart__wrapper" style="margin-top:0px; margin-bottom: 10px;"> <button type="submit" name="add" class="btn btn--splash btn--full uppercase addToCart"> <span id="AddToCartText">Add to Order</span> </button> </div> {% if product.variants.size == 1 %} <input type="hidden" id="variant-select" name="id" value="{{ product.variants.first.id }}" /> {% else %} <!-- 隐藏input:存储选中的变体ID,用于表单提交 --> <input type="hidden" id="selected-variant-id" name="id" value="{{ product.selected_or_first_available_variant.id }}" /> <!-- 按钮式变体选择器容器 --> <div class="variant-buttons-wrapper" style="display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px;"> {% for variant in product.variants %} {% assign is_selected = variant == product.selected_or_first_available_variant %} {% assign is_disabled = variant.available == false %} <button type="button" class="variant-btn {% if is_selected %}variant-btn--selected{% endif %} {% unless variant.available %}variant-btn--disabled{% endunless %}" {% unless variant.available %}disabled{% endunless %} data-variant-id="{{ variant.id }}" > {% if variant.available %} {{ variant.title }} {% else %} {{ variant.title }} - {{ 'products.product.sold_out' | t }} {% endif %} </button> {% endfor %} </div> {% endif %} </form> <!-- 按钮交互逻辑 --> <script> document.addEventListener('DOMContentLoaded', function() { const variantButtons = document.querySelectorAll('.variant-btn'); const selectedVariantInput = document.getElementById('selected-variant-id'); variantButtons.forEach(button => { button.addEventListener('click', function() { if (this.disabled) return; // 移除所有按钮的选中状态 variantButtons.forEach(btn => btn.classList.remove('variant-btn--selected')); // 标记当前按钮为选中状态 this.classList.add('variant-btn--selected'); // 更新隐藏input的变体ID值 selectedVariantInput.value = this.dataset.variantId; }); }); }); </script> <!-- 基础样式(可根据主题调整) --> <style> .variant-btn { padding: 8px 16px; border: 1px solid #ddd; border-radius: 4px; background-color: #fff; cursor: pointer; transition: all 0.2s ease; } .variant-btn--selected { background-color: #000; color: #fff; border-color: #000; } .variant-btn--disabled { background-color: #f5f5f5; color: #999; cursor: not-allowed; border-color: #eee; } </style> {% endunless %}
关键说明
- 隐藏input作用:替代原
<select>的name="id"字段,负责向购物车提交选中的变体ID,确保原有加购逻辑不受影响。 - 按钮状态控制:通过Liquid模板语法判断变体是否可用、是否为默认选中,给按钮添加对应的类名和
disabled属性。 - 交互逻辑:JavaScript处理按钮点击时的选中状态切换,同步更新隐藏input的值,保证表单提交的是正确的变体ID。
- 样式自定义:提供的基础样式可根据店铺主题的配色、布局需求调整,比如修改按钮大小、圆角、选中态颜色等。
额外注意事项
- 如果主题使用了AJAX加购逻辑,需要确认新的隐藏input的ID(
selected-variant-id)是否和原有JS逻辑匹配,如有冲突可调整ID名称。 - 若需要同步切换变体的价格、库存信息,可以扩展JavaScript逻辑,在按钮点击时更新对应DOM元素的内容。
内容的提问来源于stack exchange,提问作者Sao Ho
相关产品推荐
相关产品推荐

