javascript - 变体单击/选择时的变体元字段更新
问题描述
我有一种情况,我被卡住了。我必须更新 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'];
}));
});
}
});
}
});
}
}
解决方案
推荐阅读
- apache - Apache:在应用了 RewriteCond 的情况下使用 VirtualHost 重定向到 URL?
- excel - Excel 集合变量
- java - Kotlin 类在 variant.javaCompiler.doLast 上不可用
- python - Tensorflow 无法在 GPU 上启动会话
- windows - 在 Python 中获取文件复制的输入
- python - 正则表达式不匹配取决于字数
- javascript - Three.js GLTFLoader 在节点服务器上不起作用
- unix - 在谷歌表格中打开从 Unix 创建的 csv 文件
- python - 如何为用户定义的小数位的“e”生成一个近似值
- c# - C# 进程 - 找不到“MultiDigiMon”exe 实用程序