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

Shopify Bundle Builder自定义模板JS计数器更新异常如何解决?

问题描述

我JS开发经验不多,如果是低级问题还请见谅。我写了如下脚本统计添加到商品组合的商品数量:

var currentItems=0;
function addItem(){
    ++currentItems;
    /*if(currentItems>3){
        currentItems=3;
    }*/
    console.log("Item added");
    update();
}
  
function removeItem(){
    --currentItems;
    /*if(currentItems<0){
        currentItems=0;
    }*/
    console.log("Item removed");
    update();
}
  
function update(){
    console.log(currentItems);
}

addItem和removeItem事件通过按钮的onclick属性触发。查看控制台时,"Item added"和"Item removed"提示都能正常显示,但currentItems的数值显示错误:点击触发addItem的按钮时,不管我已经添加了多少商品,控制台始终输出1;点击触发removeItem的按钮时控制台始终输出-1,看起来变量每次点击都会从0开始计数,请问该如何修复这个问题?


补充:完整代码

我正在Shopify Bundle Builder应用中开发自定义模板,因此除了CSS样式和我写的脚本外,其余内容都是默认生成的。

<style type="text/css">
    .product-box {
        display: flex;
        width: 50%;
        float: left;
        margin-left:15%;
    }
    .product {
        display: flex;
        flex-direction: column;
    }
    .note-field--container {
        display: flex;
        flex-direction: column;
    }
    .bundle-content{
        width:20%;
        float:left;
        margin-right:5%;
    }
    #outside-progress{
        background-color:grey;
        width: 30%;
    }
    #inside-progress{
        background-color:#202945;
        height:30px;
    }
</style>

<script type="text/javascript">
const selectedVariants = new Map();

function setAddDisabled(form) {
    const variantId = form.querySelector('[name="variant"]').value;
    const sectionId = form.querySelector('[name="section"]').value;
    const canAdd = window.BundleBuilder.canAddVariant(variantId, sectionId);
    form.querySelector('[type="submit"]').disabled = !canAdd;
}


/* 变体变更后更新变体价格 */
Array.prototype.forEach.call(
    document.querySelectorAll('.bundle-builder--add-to-bundle-form select[name="variant"]'),
    function (select) {
        select.addEventListener('change', function (e) {
            const variantId = e.target.value;
            selectedVariants.set(e.target.id, variantId);
            const price = e.target.querySelector('option[value="' + variantId + '"]').dataset.price;
            e.target.parentNode.querySelector('.variant-price').textContent = price;

           const form = e.target.parentElement;
           setAddDisabled(form);
        });
    }
);


function render() {
    selectedVariants.forEach(function (variantId, selectId) {
        const select = document.getElementById(selectId);
        if (select) {
            select.value = variantId;
        }
    });
    Array.prototype.forEach.call(
        document.querySelectorAll('.bundle-builder--add-to-bundle-form'),
        setAddDisabled,
    );
}
    
/* 恢复上次选中的变体 */
document.body.addEventListener('bundlebuilder:render', render);
render()
  

</script>

{% if bundle.published %}
    <h1>{{ bundle.current_section.name }}</h1>
    <div id="outside-progress">
      <div id="inside-progress"></div>
    </div>
    <div class="product-box">
        {% for product in bundle.current_section.products %}
            <div class="product">
                <h2>{{ product.title }}</h2>
                <img src="{{ product.image.src }}" />
                {% add_to_bundle_form bundle.current_section %}
                    {% if product.available_variants.size > 1 %}
                        <select name="variant" id="select-{{ bundle.current_section.index }}-{{ product.id }}">
                            {% for variant in product.available_variants %}
                                <option value="{{ variant.id }}" data-price={{ variant.price | money }}>
                                    {{ variant.title }}{% if variant.available_count %} (available: {{ variant.available_count }}){% endif %}
                                </option>
                            {% endfor %}
                        </select>
                    {% else %}
                        <input type="hidden" name="variant" value="{{ product.available_variants[0].id }}" />
                        {{ product.available_variants[0].title }}{% if product.available_variants[0].available_count %} (available: {{ product.available_variants[0].available_count }}){% endif %}
                    {% endif %}
                    <span class="variant-price">{{ product.available_variants[0].price | money }}</span>
                    <button type="submit" style="color:#ffffff; background-color:#202945;" onclick="addItem()">Add</button>
                {% end_add_to_bundle_form %}
                {% for variant in product.variants_in_bundle %}
                  {% change_quantity_form %}
                      {% comment %}{{ variant.title }}{% endcomment %}
                      <input type="hidden" name="variant" value="{{ variant.id }}" />
                      <input type="hidden" name="section" value="{{ bundle.current_section.index }}" />
                      <button type="submit" name="remove" onClick="removeItem()">-</button>
                          {{ variant.count }}
                      <button type="submit" name="add" onclick="addItem()">+</button>
                  {% end_change_quantity_form %}
               {% endfor %}
            </div>
        {% endfor %}
    </div>

    {% if bundle.has_next_section %}
        {% section_switch_form %}
            <input type="hidden" name="section" value="{{ bundle.current_section.index | plus: 1 }}" />
            <button type="submit" style="color:#ffffff; background-color:#202945;">Next</button>
        {% end_section_switch_form %}
    {% endif %}

    {% if bundle.has_prev_section %}
        {% section_switch_form %}
            <input type="hidden" name="section" value="{{ bundle.current_section.index | plus: -1 }}" />
            <button type="submit" style="color:#ffffff; background-color:#202945;">Previous</button>
        {% end_section_switch_form %}
    {% endif %}

    {% if bundle.errors.size > 0 %}
        <ul>
            {% for error in bundle.errors %}
                <li>{{ error }}</li>
            {% endfor %}
        </ul>
    {% endif %}

    <div class="bundle-content">
        {% if bundle.content.items.size == 0 %}
            <span>Your bundle is empty</span>
        {% else %}
            <table>
                <tr>
                    <th>Product</th>
                    <th>Variant</th>
                    <th>Price</th>
                    <th></th>
                </tr>
                {% for item in bundle.content.items %}
                    <tr>
                        <td>{{ item.variant.product.title }}</td>
                        <td>{{ item.variant.title }}</td>
                        <td>{{ item.variant.price | money }}</td>
                        <td>
                            {% unless item.is_required %}
                                {% remove_from_bundle_form item %}
                                    <button type="submit" style="color:#ffffff; background-color:#202945;" name="remove" onclick="removeItem()">Remove</button>
                                {% end_remove_from_bundle_form %}
                            {% endunless %}
                        </td>
                    </tr>
                {% endfor %}
                {% if bundle.content.price < bundle.content.compare_at_price %}
                    <tr>
                        <th colspan="2">Discount</th>
                        <th>
                            <span>{{ bundle.content.price | minus: bundle.content.compare_at_price | money }}</span>
                        </th>
                        <th></th>
                    </tr>
                {% endif %}
                <tr>
                    <th colspan="2">Total</th>
                    <th>
                        <span>{{ bundle.content.price | money }}</span>
                    </th>
                    <th></th>
                </tr>
            </table>

            {% if settings.note_enabled %}
                <div class="note-field--container">
                    <label>{{ settings.note_label }}{% if settings.note_required %} (required){% endif %}</label>
                    {% note_field %}{{ settings.note_text }}{% end_note_field %}
                </div>
                {% if settings.note_prompt_visible %}
                    <div class="note-field--error-message">
                        <p>Note required before adding to cart.</p>
                    </div>
                {% endif %}
            {% endif %}

            {% add_to_cart_form %}
                {% if bundle.subscription_type == 'optional' and bundle.subscription_frequencies.size > 0 %}
                    <label>
                        <input type="radio" name="subscription-enabled" value="0" />
                        One-time purchase
                    </label>
                    <label>
                        <input type="radio" name="subscription-enabled" value="1" />
                        Subscribe
                    </label>
                {% endif %}
                {% if bundle.subscription_type == 'required' or bundle.subscription_enabled %}
                    {% for frequency in bundle.subscription_frequencies %}
                        <ul>
                            <li>
                                <label>
                                    <input type="radio" name="subscription-frequency" value="{{ frequency.id }}" />
                                    {{ frequency.frequency }} {{ frequency.unit }}
                                </label>
                            </li>
                        </ul>
                    {% endfor %}
                    Email: <input type="email" required name="subscription-email" value="{{ settings.subscription_email }}" />
                {% endif %}
                <button type="submit"{% unless bundle.can_add_to_cart %} disabled="disabled"{% endunless %} style="color:#ffffff; background-color:#202945;">
                    {% if bundle.adding_to_cart %}
                        Processing...
                    {% else %}
                        Add bundle to cart
                    {% endif %}
                </button>
            {% end_add_to_cart_form %}
        {% endif %}
    </div>
{% else %}
    <p>Sorry, this bundle is currently unavailable.</p>
{% endif %}

<script type="text/javascript">
/* 自定义进度条 */
const progress = document.getElementById("inside-progress");
var currentItems=0;
function addItem(){
    ++currentItems;
    /*if(currentItems>3){
        currentItems=3;
    }*/
    console.log("Item added");
    update();
}
  
function removeItem(){
    --currentItems;
    /*if(currentItems<0){
        currentItems=0;
    }*/
    console.log("Item removed");
    update();
}
  
function update(){
    console.log(currentItems);
}
</script>

问题原因与修复方案

正如多位网友指出的,submit类型的按钮每次点击都会重新加载页面,因此无法保留运行时计数。通过使用sessionStorage存储计数值可以修复该问题,修复后的代码如下:

function addItem(){
    window.sessionStorage.setItem('count',Number(window.sessionStorage.getItem('count'))+1);
    /*if(currentItems>3){
        currentItems=3;
    }*/
    console.log("Item added");
    update();
}
  
function removeItem(){
    window.sessionStorage.setItem('count',Number(window.sessionStorage.getItem('count'))-1);
    /*if(currentItems<0){
        currentItems=0;
    }*/
    console.log("Item removed");
    update();
}
  
function update(){
    console.log(Number(window.sessionStorage.getItem('count')));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:27:02