首页 > 解决方案 > 变体单击/选择时的变体元字段更新

问题描述

我有一种情况,我被卡住了。我必须更新 product-info.liquid 和 Product-item.liquid 并添加 Inc Vat 和 Exc Vat 的价格。幸运的是,我这样做了,并附上了结果图像。我只是用 {{product.price | 添加了 Inc VAT 和 EXC VAT 钱}} 和所需的百分比。

成功的第一张图片

使用 Variant ID 进行 Variant Swith URL 更改

刷新页面价格与成功

我希望价格像我在变体开关上一样显示,而不是刷新页面。据我所知,这是一个 JavaScript 触发器。但我不知道在哪里进行修改以获得我想要的结果。我相信下面的代码需要编辑,在这里我请求有人过来告诉我正确的路径,以便在我被卡住的地方继续前进。

/**
   * ---------------------------------------------------------------------------------------------------
   * CODE THAT HANDLE VARIANT CHANGES IN THE FRONT
   *
   * Please note that this code is highly dependant on the markup and classes, so make sure to NOT
   * edit this code
   * ---------------------------------------------------------------------------------------------------
   */

  /**
   * This callback is called whenever the variant changes and allows to update data about the active variant
   */

}, {
  key: "_onVariantChanged",
  value: function _onVariantChanged(previousVariant, newVariant) {
    // 1st: the prices
    this._updateProductPrices(newVariant, previousVariant); // 2th: update inventory


    this._updateInventory(newVariant, previousVariant); // 3th: update SKU


    this._updateSku(newVariant, previousVariant); // 4th: update the discount label (if necessary)


    this._updateDiscountLabel(newVariant, previousVariant); // 5th: update the unit price (if necessary)


    this._updateUnitPrice(newVariant, previousVariant); // 6th: update selectors


    this._updateSelectors(newVariant, previousVariant); // 7th: the add to cart button


    this._updateAddToCartButton(newVariant, previousVariant); // 8th: store availability


    this.storeAvailability.updateWithVariant(newVariant); // Finally, we send an event so that other system could hook and do their own logic

    this.element.dispatchEvent(new CustomEvent('variant:changed', {
      bubbles: true,
      detail: {
        variant: newVariant,
        previousVariant: previousVariant
      }
    }));
  }
  /**
   * Update the prices (optionally showing compare at price)
   */

}, {
  key: "_updateProductPrices",
  value: function _updateProductPrices(newVariant, previousVariant) {
    var productPrices = this.element.querySelector('.price-list');

    if (!productPrices) {
      return; // Sometimes merchant remove element from the code without taking care of JS... so let's be defensive
    }

    if (!newVariant) {
      productPrices.style.display = 'none';
    } else {
      if (previousVariant && previousVariant['price'] === newVariant['price'] && previousVariant['compare_at_price'] === newVariant['compare_at_price']) {
        return; // The price do not have changed so let's return to avoid changing the DOM for nothing
      }

      productPrices.innerHTML = '';

      if (newVariant['compare_at_price'] > newVariant['price']) {
        productPrices.innerHTML += "<span class=\"price price--highlight\"><span class=\"visually-hidden\">".concat(window.languages.productSalePrice, "</span>").concat(Currency.formatMoney(newVariant['price'], window.theme.moneyFormat), "</span>");
        productPrices.innerHTML += "<span class=\"price price--compare\"><span class=\"visually-hidden\">".concat(window.languages.productRegularPrice, "</span>").concat(Currency.formatMoney(newVariant['compare_at_price'], window.theme.moneyFormat), "</span>");
      } else {
        productPrices.innerHTML += "<span class=\"price\"><span class=\"visually-hidden\">".concat(window.languages.productSalePrice, "</span>").concat(Currency.formatMoney(newVariant['price'], window.theme.moneyFormat), "</span>");
      }

      productPrices.style.display = '';
    }
  }
  /**
   * Update the inventory (if needed)
   */

}, {
  key: "_updateInventory",
  value: function _updateInventory(newVariant) {
    if (!this.options['showInventoryQuantity'] || !newVariant) {
      return;
    }

    var productFormInventoryElement = this.element.querySelector('.product-form__inventory'),
        variantInventoryManagement = this.variantsInventories[newVariant['id']]['inventory_management'],
        variantInventoryPolicy = this.variantsInventories[newVariant['id']]['inventory_policy'],
        variantInventoryQuantity = this.variantsInventories[newVariant['id']]['inventory_quantity'],
        variantInventoryMessage = this.variantsInventories[newVariant['id']]['inventory_message'];

    if (!productFormInventoryElement) {
      return; // Sometimes merchant remove element from the code without taking care of JS... so let's be defensive
    }

    productFormInventoryElement.classList.remove('inventory--high');
    productFormInventoryElement.classList.remove('inventory--low');

    if (newVariant['available']) {
      if (null !== variantInventoryManagement && variantInventoryPolicy === 'deny' && this.options['lowInventoryThreshold'] > 0) {
        if (variantInventoryQuantity <= this.options['lowInventoryThreshold']) {
          productFormInventoryElement.classList.add('inventory--low');
        } else {
          productFormInventoryElement.classList.add('inventory--high');
        }
      } else {
        productFormInventoryElement.classList.add('inventory--high');
      }
    } // We also need to update the stock countdown if setup


    var stockCountdown = this.element.querySelector('.inventory-bar');

    if (stockCountdown) {
      var stockCountdownProgress = Math.min(Math.max(variantInventoryQuantity / parseInt(stockCountdown.getAttribute('data-stock-countdown-max')) * 100.0, 0), 100);
      stockCountdown.classList.toggle('inventory-bar--hidden', stockCountdownProgress === 0);
      stockCountdown.firstElementChild.style.width = "".concat(stockCountdownProgress, "%");
    }

    productFormInventoryElement.innerHTML = variantInventoryMessage;
  }
  /**
   * Update SKU
   */

}, {
  key: "_updateSku",
  value: function _updateSku(newVariant, previousVariant) {
    var productSku = this.element.querySelector('.product-meta__sku');

    if (!productSku) {
      return;
    }

    var productSkuNumber = productSku.querySelector('.product-meta__sku-number');

    if (!newVariant || newVariant['sku'] === '') {
      productSku.style.display = 'none';
    } else {
      if (previousVariant && previousVariant['sku'] === newVariant['sku']) {
        return; // The SKU do not have changed so let's return to avoid changing the DOM for nothing
      }

      productSkuNumber.innerHTML = newVariant['sku'];
      productSku.style.display = '';
    }
  }
  /**
   * Update the discount label
   */

}, {
  key: "_updateDiscountLabel",
  value: function _updateDiscountLabel(newVariant, previousVariant) {
    if (!window.theme.showDiscount) {
      return; // Nothing to do if discount label is configured to be hidden
    }

    var discountLabel = this.element.querySelector('.product-meta .product-label--on-sale'); // Some merchants have removed it from the code so we have to act defensive

    if (!discountLabel) {
      return;
    }

    if (!newVariant || !(newVariant['price'] < newVariant['compare_at_price'])) {
      discountLabel.style.display = 'none';
    } else {
      // We compute the savings based on the setting
      var savings = null;

      if (window.theme.discountMode === 'percentage') {
        savings = "".concat(Math.round((newVariant['compare_at_price'] - newVariant['price']) * 100 / newVariant['compare_at_price']), "%");
      } else {
        savings = "<span>".concat(Currency.formatMoney(newVariant['compare_at_price'] - newVariant['price'], window.theme.moneyFormat), "</span>");
      }

      discountLabel.innerHTML = "".concat(window.languages.collectionOnSaleLabel.replace('{{savings}}', savings));
      discountLabel.style.display = 'inline-block';
    }
  }
}, {
  key: "_updateUnitPrice",
  value: function _updateUnitPrice(newVariant, previousVariant) {
    var unitPriceMeasurement = this.element.querySelector('.unit-price-measurement');

    if (!unitPriceMeasurement) {
      return; // Sometimes merchant remove element from the code without taking care of JS... so let's be defensive
    }

    if (!newVariant || !newVariant['unit_price_measurement']) {
      unitPriceMeasurement.parentNode.style.display = 'none';
    } else {
      unitPriceMeasurement.parentNode.style.display = 'block';
      unitPriceMeasurement.querySelector('.unit-price-measurement__price').innerHTML = Currency.formatMoney(newVariant['unit_price'], window.theme.moneyFormat);
      unitPriceMeasurement.querySelector('.unit-price-measurement__reference-unit').innerHTML = newVariant['unit_price_measurement']['reference_unit'];
      var unitPriceReferenceValue = unitPriceMeasurement.querySelector('.unit-price-measurement__reference-value');
      unitPriceReferenceValue.innerHTML = newVariant['unit_price_measurement']['reference_value'];
      unitPriceReferenceValue.style.display = newVariant['unit_price_measurement']['reference_value'] === 1 ? 'none' : 'inline';
    }
  }
  /**
   * Warehouse automatically adds a "disabled" state to sold out/unavailable variant. When we change the variant we have to recompute
   * all the selectors
   */

}, {
  key: "_updateSelectors",
  value: function _updateSelectors(newVariant) {
    var _this2 = this;

    // We apply a top-down approach where we first check the first option, second option and third option. If there is
    // more than one option, the value is considered "available" if there is at least one variant with this value
    // available (independently of the selected variant)
    var applyClassToSelector = function applyClassToSelector(selector, valueIndex, available) {
      var selectorType = selector.getAttribute('data-selector-type');

      switch (selectorType) {
        case 'color':
          selector.querySelector(".color-swatch:nth-child(".concat(valueIndex + 1, ")")).classList.toggle('color-swatch--disabled', !available);
          break;

        case 'variant':
          selector.querySelector(".variant-swatch:nth-child(".concat(valueIndex + 1, ")")).classList.toggle('variant-swatch--disabled', !available);
          break;

        case 'block':
          selector.querySelector(".block-swatch:nth-child(".concat(valueIndex + 1, ")")).classList.toggle('block-swatch--disabled', !available);
          break;
      }
    };

    if (this.variantSelectors && this.variantSelectors[0]) {
      // For the first option, the value is considered available if there is at least one variant available
      this.productOptionsWithValues[0]['values'].forEach(function (value, valueIndex) {
        applyClassToSelector(_this2.variantSelectors[0], valueIndex, _this2.productData['variants'].some(function (variant) {
          return variant['option1'] === value && variant['available'];
        })); // We now do the second level

        if (_this2.variantSelectors[1]) {
          _this2.productOptionsWithValues[1]['values'].forEach(function (value, valueIndex) {
            applyClassToSelector(_this2.variantSelectors[1], valueIndex, _this2.productData['variants'].some(function (variant) {
              return variant['option2'] === value && variant['option1'] === _this2.option1 && variant['available'];
            })); // And finally the third level

            if (_this2.variantSelectors[2]) {
              _this2.productOptionsWithValues[2]['values'].forEach(function (value, valueIndex) {
                applyClassToSelector(_this2.variantSelectors[2], valueIndex, _this2.productData['variants'].some(function (variant) {
                  return variant['option3'] === value && variant['option1'] === _this2.option1 && variant['option2'] === _this2.option2 && variant['available'];
                }));
              });
            }
          });
        }
      });
    }
  }

标签: javascriptshopify

解决方案


推荐阅读