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

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。
  • 样式自定义:提供的基础样式可根据店铺主题的配色、布局需求调整,比如修改按钮大小、圆角、选中态颜色等。

额外注意事项

  1. 如果主题使用了AJAX加购逻辑,需要确认新的隐藏input的ID(selected-variant-id)是否和原有JS逻辑匹配,如有冲突可调整ID名称。
  2. 若需要同步切换变体的价格、库存信息,可以扩展JavaScript逻辑,在按钮点击时更新对应DOM元素的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:50:26