使用 Shopify 通过 Javascript 动态拉取 Variant id
Dynamically pulling Variant id via Javascript using Shopify
我一直在处理 Shopify 商店的一个共同请求,即 "Add to cart button" 商店使用 "Debut" 主题。目标是在单击 "add to cart button" 时自动更新购物车,而无需跳转到购物车页面,让客户留在页面上以方便使用等。
现在通常这不是什么大问题,因为网络上有很多关于该主题的资源 material。我通常可以 "google my way to freedom"
这是我为达到这一点而引用的一些链接
将以下代码添加到 product-card-grid.liquid
后,添加到购物车按钮工作正常
<form method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
<input min="1" type="number" id="quantity" name="quantity" value="1"/>
<input type="submit" value="Add to cart" class="btn" />
</form>
问题:
我 运行 遇到的问题是我的 collection 页面使用了边栏过滤器。除了 collection 页面之外,代码在任何地方都有效。通过一些挖掘和一些检查,我发现这可能是因为 sidebar/collection 页面中的产品是由 theme.js 文件中的一些代码填充的。
现在这绝对是我盲目的地方,Javascript 是我想要更熟悉的东西,但是对于所有事情都需要时间。
所以...我通过仔细阅读 theme.js 文件注意到,如果格式正确,html 可以添加到 js。我能够插入它并让“添加到购物车”按钮显示在我的 sidebar/collection 页面中。小胜利!但是不太管用。
Collection Page Screenshot
单击 "add to cart" 按钮时出现以下错误
"数组包含不允许的成员:id"
Array contains... Error pic
这是 theme.js 文件中的一些代码,我希望可以对其进行修改
function runFilter() {
typeFilter(typebxs);
vendorFilter(vendorbxs);
tagsFilter(tagbxs);
optionsFilter(optionsbxs);
colorFilter(colorbxs);
sizeFilter(sizebxs);
var has_price_filter = document.getElementById("sidebar-product-price").innerHTML;
if ( has_price_filter == "true" ) {
priceFilter(pricebxs);
} else {
passedpricefiltertest = "true";
}
if ( passedtagfiltertest == "true"
&& passedtypefiltertest == "true"
&& passedpricefiltertest == "true"
&& passedvendorfiltertest == "true"
&& passedoptionsfiltertest == "true"
&& passedcolorfiltertest == "true"
&& passedsizefiltertest == "true" ) {
var money_sign = document.getElementById("money-sign").innerHTML; money_sign = money_sign.replace("0.00", "");
if ( varaints_min_price != varaints_max_price ) { var price_string = money_sign + parseFloat((varaints_min_price)).toFixed(2) + "+" } else { var price_string = money_sign + parseFloat((varaints_min_price)).toFixed(2); }
var product_url = collection_url +"products/"+ val.handle;
var product_images_ratio = document.getElementById("product_images_ratio").innerHTML;
var product_image_url = val.images[0].src.replace(".jpg", "_600x600.jpg");
product_image_url = product_image_url.replace(".png", "_600x600.png");
if (val.variants[0].available == true) { var sold_out = ''; } else { var sold_out = ' product-price--sold-out grid-view-item--sold-out'; }
var string1 = '<div class="grid__item grid__item--' + sectionid + ' ' + grid_item_width + '"><div class="grid-view-item' + sold_out + '" data-section-id="section.id" data-section-type="collection-template"><div class="product-container"><div class="collection-product-overlay"><a class="grid-view-item__link" href="' + product_url + '">';
if (product_images_ratio == "none") { var string2 = '<div style="display:none;" id="product-image-align">false</div><div style="display:none;" id="product-image-ratio">' + product_images_ratio + '</div><img class="grid-view-item__image" src="' + product_image_url + '" alt="">'; } else { var string2 = '<div class="image-bar__item box ratio-container lazyload product-grid-image"data-bgset="' + product_image_url + '" data-sizes="auto" data-parent-fit="contain" style=" background-size: contain; background-color: transparent; background-attached:fixed; background-position: center; background-image: url("' + product_image_url + '");"></div><div style="display:none;" id="product-image-align">true</div><div style="display:none;" id="product-image-ratio">' + product_images_ratio + '</div>'; }
if (show_vendor == "true") { var string3 = '<div style="" class="h4 grid-view-item__title collection-title_wrapper">' + val.title + '</div><div class="grid-view-item__vendor collection-title_wrapper">' + val.vendor + '</div>'; } else { var string3 = '<div style="" class="h4 grid-view-item__title collection-title_wrapper">' + val.title + '</div>'; }
if ( val.variants[0].compare_at_price > val.variants[0].price ) { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="visually-hidden">Regular price</span><s class="product-price__price" style="">' + money_sign + val.compare_at_price + '</s><span class="product-price__price product-price__sale" style="">' + price_string + '<span class="product-price__sale-label">Sale</span></span>'; } else { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="product-price__price" style="">' + price_string + '</span>' + '<form class="addtocart"method="post" action="/cart/add"><input type="hidden" name="id" value="quantity" /><input min="1" type="number" id="{{ product.variants.first.id }}" name="quantity" value="1"/><input type="submit" value="Add to cart" class="btn" /></form>' ; }
if ( val.variants[0].available == true ) { var string5 = '</div></a></div></div></div></div>'; } else { var string5 = '<span class="product-price__sold-out" style="">Sold out</span></div></a></div></div></div>'; }
var string = string1 + string2 + string3 + string4 + string5;
filteredProducts.push(val.title+val.id);
productGrid[val.title+val.id] = [string];
if (total_json_pages == counter2) {
if (counter3 == collectionLength) {
circle.animate(1,{
duration: (100)
});
debouncedPagintor();
}
}
if ( product_images_ratio != "none" ) {
var width = $( ".product-grid-image" ).width();
width = parseInt(width) * parseFloat(product_images_ratio) ;
$( ".product-grid-image" ).css( "height", width );
}
} else {
if (total_json_pages == counter2) {
if (counter3 == collectionLength) {
debouncedPagintor();
}
}
}
}
runFilter();
}
}
$('.filter-update ~ .lbl, .filter-update ~ .cbx').unbind("click");
$('.filter-update ~ .lbl, .filter-update ~ .cbx').on( "click", function() {
debouncedfilterIt();
});
}
var debouncedfilterIt = function() {
filterIt();
}
var debouncedfilterIt = $.debounce( 250, false, debouncedfilterIt );
var needsFilter = document.getElementById('sb-master-input-format-1');
function grabCollection() {
var show_vendor = document.getElementById("show_vendor").innerHTML;
var grid_item_width = document.getElementById("grid_item_width").innerHTML;
var sectionid = sectionId;
var money_sign = document.getElementById("money-sign").innerHTML;
money_sign = money_sign.replace("0.00", "");
var filteredProducts = [];
var jsonDataString = "";
var jsonData = {};
if (masterString[jsonsrc + "1"] == undefined) {
if ( total_json_pages > 2 ) {
$( "#progress" ).show();
circle.animate(1,{
duration: ((total_json_pages)*200)
});
您可以看到我在 collection 页面上插入 html 以加载按钮的位置。我所做的唯一修改是插入包含在 "form" 标记中的 html 位。
我相信有问题的位很可能会在特别长的代码行中找到
来自那个文件
if ( val.variants[0].compare_at_price > val.variants[0].price ) { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="visually-hidden">Regular price</span><s class="product-price__price" style="">' + money_sign + val.compare_at_price + '</s><span class="product-price__price product-price__sale" style="">' + price_string + '<span class="product-price__sale-label">Sale</span></span>'; } else { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="product-price__price" style="">' + price_string + '</span>' + '<form class="addtocart"method="post" action="/cart/add"><input type="hidden" name="id" value="quantity" /><input min="1" type="number" id="{{ product.variants.first.id }}" name="quantity" value="1"/><input type="submit" value="Add to cart" class="btn" /></form>' ; }
这是我第一次发帖。如果我错过了为本论坛设置格式的更简单方法,我深表歉意。
我希望这就足够了。我快到了吗?这是一个简单的修复吗?信息不足?
感谢您的宝贵时间!我希望这足够彻底,不要太复杂。
此致
杰夫·J
编辑:
我快到了! (感谢 Darshit Patel!)在 theme.js 中将 "{{ product.variants.first.id }}"
更改为 "'+ val.variants[0].id +'"
摆脱了 "array contains unpermitted members: id" 错误并更新购物车,但它会将我带到购物车页面并且似乎没有与 ajaxify-cart.liquid
交互
这是完整的 ajaxify-cart.liquid 代码
<script>
/**
* Module to ajaxify all add to cart forms on the page.
*
* Copyright (c) 2015 Caroline Schnapp (11heavens.com)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
Shopify.AjaxifyCart = (function($) {
// Some configuration options.
// I have separated what you will never need to change from what
// you might change.
var _config = {
// What you might want to change
addToCartBtnLabel: 'Add to cart',
addedToCartBtnLabel: 'Thank you!',
addingToCartBtnLabel: 'Adding...',
soldOutBtnLabel: 'Sold Out',
howLongTillBtnReturnsToNormal: 1000, // in milliseconds.
cartCountSelector: '#CartCount, .cart-count, #cart-count a:first, #gocart p a, #cart .checkout em, .item-count',
cartTotalSelector: '#cart-price',
// 'aboveForm' for top of add to cart form,
// 'belowForm' for below the add to cart form, and
// 'nextButton' for next to add to cart button.
feedbackPosition: 'nextButton',
// What you will never need to change
addToCartBtnSelector: '[type="submit"]',
addToCartFormSelector: 'form[action="/cart/add"]',
shopifyAjaxAddURL: '/cart/add.js',
shopifyAjaxCartURL: '/cart.js'
};
// We need some feedback when adding an item to the cart.
// Here it is.
var _showFeedback = function(success, html, $addToCartForm) {
$('.ajaxified-cart-feedback').remove();
var feedback = '<p class="ajaxified-cart-feedback ' + success + '">' + html + '</p>';
switch (_config.feedbackPosition) {
case 'aboveForm':
$addToCartForm.before(feedback);
break;
case 'belowForm':
$addToCartForm.after(feedback);
break;
case 'nextButton':
default:
$addToCartForm.find(_config.addToCartBtnSelector).after(feedback);
break;
}
// If you use animate.css
// $('.ajaxified-cart-feedback').addClass('animated bounceInDown');
$('.ajaxified-cart-feedback').slideDown();
};
var _setText = function($button, label) {
if ($button.children().length) {
$button.children().each(function() {
if ($.trim($(this).text()) !== '') {
$(this).text(label);
}
});
}
else {
$button.val(label).text(label);
}
};
var _init = function() {
$(document).ready(function() {
$(_config.addToCartFormSelector).submit(function(e) {
e.preventDefault();
var $addToCartForm = $(this);
var $addToCartBtn = $addToCartForm.find(_config.addToCartBtnSelector);
_setText($addToCartBtn, _config.addingToCartBtnLabel);
$addToCartBtn.addClass('disabled').prop('disabled', true);
// Add to cart.
$.ajax({
url: _config.shopifyAjaxAddURL,
dataType: 'json',
type: 'post',
data: $addToCartForm.serialize(),
success: function(itemData) {
// Re-enable add to cart button.
$addToCartBtn.addClass('inverted');
_setText($addToCartBtn, _config.addedToCartBtnLabel);
_showFeedback('success','<i class="fa fa-check"></i> Added to cart! <a href="/cart">View cart</a> or <a href="/collections/all">continue shopping</a>.',$addToCartForm);
window.setTimeout(function(){
$addToCartBtn.prop('disabled', false).removeClass('disabled').removeClass('inverted');
_setText($addToCartBtn,_config.addToCartBtnLabel);
}, _config.howLongTillBtnReturnsToNormal);
// Update cart count and show cart link.
$.getJSON(_config.shopifyAjaxCartURL, function(cart) {
if (_config.cartCountSelector && $(_config.cartCountSelector).size()) {
var value = $(_config.cartCountSelector).html() || '0';
$(_config.cartCountSelector).html(value.replace(/[0-9]+/,cart.item_count)).removeClass('hidden-count');
}
if (_config.cartTotalSelector && $(_config.cartTotalSelector).size()) {
if (typeof Currency !== 'undefined' && typeof Currency.moneyFormats !== 'undefined') {
var newCurrency = '';
if ($('[name="currencies"]').size()) {
newCurrency = $('[name="currencies"]').val();
}
else if ($('#currencies span.selected').size()) {
newCurrency = $('#currencies span.selected').attr('data-currency');
}
if (newCurrency) {
$(_config.cartTotalSelector).html('<span class=money>' + Shopify.formatMoney(Currency.convert(cart.total_price, "{{ shop.currency }}", newCurrency), Currency.money_format[newCurrency]) + '</span>');
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
}
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
}
};
});
},
error: function(XMLHttpRequest) {
var response = eval('(' + XMLHttpRequest.responseText + ')');
response = response.description;
if (response.slice(0,4) === 'All ') {
_showFeedback('error', response.replace('All 1 ', 'All '), $addToCartForm);
$addToCartBtn.prop('disabled', false);
_setText($addToCartBtn, _config.soldOutBtnLabel);
$addToCartBtn.prop('disabled',true);
}
else {
_showFeedback('error', '<i class="fa fa-warning"></i> ' + response, $addToCartForm);
$addToCartBtn.prop('disabled', false).removeClass('disabled');
_setText($addToCartBtn, _config.addToCartBtnLabel);
}
}
});
return false;
});
});
};
return {
init: function(params) {
// Configuration
params = params || {};
// Merging with defaults.
$.extend(_config, params);
// Action
$(function() {
_init();
});
},
getConfig: function() {
return _config;
}
}
})(jQuery);
Shopify.AjaxifyCart.init();
</script>
{% comment %}
If you want to animate your feedback message.
{% endcomment %}
{% comment %}
{{ '//cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.0/animate.min.css' | stylesheet_tag }}
{% endcomment %}
{{ '//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css' | stylesheet_tag }}
<style>
.ajaxified-cart-feedback {
display: block;
line-height: 36px;
font-size: 90%;
vertical-align: middle;
}
.ajaxified-cart-feedback.success {
color: #3D9970;
}
.ajaxified-cart-feedback.error {
color: #FF4136;
}
.ajaxified-cart-feedback a {
border-bottom: 1px solid;
}
</style>
我想知道是否有一个简单的解决方案。我不知所措。我会把它作为一个新问题,但在这一点上它看起来确实像一个 "two parter",因为它涉及到我分享的所有信息。
再次感谢您的宝贵时间
干杯!
theme.js 中的这行代码 'id="{{ product.variants.first.id }}"' 与您在任何 .js 文件中添加的代码 issue.When 完全一致,它不会在液体中呈现,但会将其呈现为细绳。 Theme.js 是一个简单的 .js 文件,不是液体,所以这条液体线将呈现为字符串。您需要更改该行,您的问题将得到解决。
您只需要将整个 theme.js.
中的“{{ product.variants.first.id }}”替换为 "val.variants[0].id"
我一直在处理 Shopify 商店的一个共同请求,即 "Add to cart button" 商店使用 "Debut" 主题。目标是在单击 "add to cart button" 时自动更新购物车,而无需跳转到购物车页面,让客户留在页面上以方便使用等。
现在通常这不是什么大问题,因为网络上有很多关于该主题的资源 material。我通常可以 "google my way to freedom"
这是我为达到这一点而引用的一些链接
将以下代码添加到 product-card-grid.liquid
后,添加到购物车按钮工作正常 <form method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
<input min="1" type="number" id="quantity" name="quantity" value="1"/>
<input type="submit" value="Add to cart" class="btn" />
</form>
问题:
我 运行 遇到的问题是我的 collection 页面使用了边栏过滤器。除了 collection 页面之外,代码在任何地方都有效。通过一些挖掘和一些检查,我发现这可能是因为 sidebar/collection 页面中的产品是由 theme.js 文件中的一些代码填充的。
现在这绝对是我盲目的地方,Javascript 是我想要更熟悉的东西,但是对于所有事情都需要时间。
所以...我通过仔细阅读 theme.js 文件注意到,如果格式正确,html 可以添加到 js。我能够插入它并让“添加到购物车”按钮显示在我的 sidebar/collection 页面中。小胜利!但是不太管用。
Collection Page Screenshot
单击 "add to cart" 按钮时出现以下错误
"数组包含不允许的成员:id"
Array contains... Error pic
这是 theme.js 文件中的一些代码,我希望可以对其进行修改
function runFilter() {
typeFilter(typebxs);
vendorFilter(vendorbxs);
tagsFilter(tagbxs);
optionsFilter(optionsbxs);
colorFilter(colorbxs);
sizeFilter(sizebxs);
var has_price_filter = document.getElementById("sidebar-product-price").innerHTML;
if ( has_price_filter == "true" ) {
priceFilter(pricebxs);
} else {
passedpricefiltertest = "true";
}
if ( passedtagfiltertest == "true"
&& passedtypefiltertest == "true"
&& passedpricefiltertest == "true"
&& passedvendorfiltertest == "true"
&& passedoptionsfiltertest == "true"
&& passedcolorfiltertest == "true"
&& passedsizefiltertest == "true" ) {
var money_sign = document.getElementById("money-sign").innerHTML; money_sign = money_sign.replace("0.00", "");
if ( varaints_min_price != varaints_max_price ) { var price_string = money_sign + parseFloat((varaints_min_price)).toFixed(2) + "+" } else { var price_string = money_sign + parseFloat((varaints_min_price)).toFixed(2); }
var product_url = collection_url +"products/"+ val.handle;
var product_images_ratio = document.getElementById("product_images_ratio").innerHTML;
var product_image_url = val.images[0].src.replace(".jpg", "_600x600.jpg");
product_image_url = product_image_url.replace(".png", "_600x600.png");
if (val.variants[0].available == true) { var sold_out = ''; } else { var sold_out = ' product-price--sold-out grid-view-item--sold-out'; }
var string1 = '<div class="grid__item grid__item--' + sectionid + ' ' + grid_item_width + '"><div class="grid-view-item' + sold_out + '" data-section-id="section.id" data-section-type="collection-template"><div class="product-container"><div class="collection-product-overlay"><a class="grid-view-item__link" href="' + product_url + '">';
if (product_images_ratio == "none") { var string2 = '<div style="display:none;" id="product-image-align">false</div><div style="display:none;" id="product-image-ratio">' + product_images_ratio + '</div><img class="grid-view-item__image" src="' + product_image_url + '" alt="">'; } else { var string2 = '<div class="image-bar__item box ratio-container lazyload product-grid-image"data-bgset="' + product_image_url + '" data-sizes="auto" data-parent-fit="contain" style=" background-size: contain; background-color: transparent; background-attached:fixed; background-position: center; background-image: url("' + product_image_url + '");"></div><div style="display:none;" id="product-image-align">true</div><div style="display:none;" id="product-image-ratio">' + product_images_ratio + '</div>'; }
if (show_vendor == "true") { var string3 = '<div style="" class="h4 grid-view-item__title collection-title_wrapper">' + val.title + '</div><div class="grid-view-item__vendor collection-title_wrapper">' + val.vendor + '</div>'; } else { var string3 = '<div style="" class="h4 grid-view-item__title collection-title_wrapper">' + val.title + '</div>'; }
if ( val.variants[0].compare_at_price > val.variants[0].price ) { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="visually-hidden">Regular price</span><s class="product-price__price" style="">' + money_sign + val.compare_at_price + '</s><span class="product-price__price product-price__sale" style="">' + price_string + '<span class="product-price__sale-label">Sale</span></span>'; } else { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="product-price__price" style="">' + price_string + '</span>' + '<form class="addtocart"method="post" action="/cart/add"><input type="hidden" name="id" value="quantity" /><input min="1" type="number" id="{{ product.variants.first.id }}" name="quantity" value="1"/><input type="submit" value="Add to cart" class="btn" /></form>' ; }
if ( val.variants[0].available == true ) { var string5 = '</div></a></div></div></div></div>'; } else { var string5 = '<span class="product-price__sold-out" style="">Sold out</span></div></a></div></div></div>'; }
var string = string1 + string2 + string3 + string4 + string5;
filteredProducts.push(val.title+val.id);
productGrid[val.title+val.id] = [string];
if (total_json_pages == counter2) {
if (counter3 == collectionLength) {
circle.animate(1,{
duration: (100)
});
debouncedPagintor();
}
}
if ( product_images_ratio != "none" ) {
var width = $( ".product-grid-image" ).width();
width = parseInt(width) * parseFloat(product_images_ratio) ;
$( ".product-grid-image" ).css( "height", width );
}
} else {
if (total_json_pages == counter2) {
if (counter3 == collectionLength) {
debouncedPagintor();
}
}
}
}
runFilter();
}
}
$('.filter-update ~ .lbl, .filter-update ~ .cbx').unbind("click");
$('.filter-update ~ .lbl, .filter-update ~ .cbx').on( "click", function() {
debouncedfilterIt();
});
}
var debouncedfilterIt = function() {
filterIt();
}
var debouncedfilterIt = $.debounce( 250, false, debouncedfilterIt );
var needsFilter = document.getElementById('sb-master-input-format-1');
function grabCollection() {
var show_vendor = document.getElementById("show_vendor").innerHTML;
var grid_item_width = document.getElementById("grid_item_width").innerHTML;
var sectionid = sectionId;
var money_sign = document.getElementById("money-sign").innerHTML;
money_sign = money_sign.replace("0.00", "");
var filteredProducts = [];
var jsonDataString = "";
var jsonData = {};
if (masterString[jsonsrc + "1"] == undefined) {
if ( total_json_pages > 2 ) {
$( "#progress" ).show();
circle.animate(1,{
duration: ((total_json_pages)*200)
});
您可以看到我在 collection 页面上插入 html 以加载按钮的位置。我所做的唯一修改是插入包含在 "form" 标记中的 html 位。
我相信有问题的位很可能会在特别长的代码行中找到
来自那个文件
if ( val.variants[0].compare_at_price > val.variants[0].price ) { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="visually-hidden">Regular price</span><s class="product-price__price" style="">' + money_sign + val.compare_at_price + '</s><span class="product-price__price product-price__sale" style="">' + price_string + '<span class="product-price__sale-label">Sale</span></span>'; } else { var string4 = '<div class="grid-view-item__meta collection-title_wrapper"><span class="product-price__price" style="">' + price_string + '</span>' + '<form class="addtocart"method="post" action="/cart/add"><input type="hidden" name="id" value="quantity" /><input min="1" type="number" id="{{ product.variants.first.id }}" name="quantity" value="1"/><input type="submit" value="Add to cart" class="btn" /></form>' ; }
这是我第一次发帖。如果我错过了为本论坛设置格式的更简单方法,我深表歉意。
我希望这就足够了。我快到了吗?这是一个简单的修复吗?信息不足?
感谢您的宝贵时间!我希望这足够彻底,不要太复杂。
此致
杰夫·J
编辑:
我快到了! (感谢 Darshit Patel!)在 theme.js 中将 "{{ product.variants.first.id }}"
更改为 "'+ val.variants[0].id +'"
摆脱了 "array contains unpermitted members: id" 错误并更新购物车,但它会将我带到购物车页面并且似乎没有与 ajaxify-cart.liquid
这是完整的 ajaxify-cart.liquid 代码
<script>
/**
* Module to ajaxify all add to cart forms on the page.
*
* Copyright (c) 2015 Caroline Schnapp (11heavens.com)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
Shopify.AjaxifyCart = (function($) {
// Some configuration options.
// I have separated what you will never need to change from what
// you might change.
var _config = {
// What you might want to change
addToCartBtnLabel: 'Add to cart',
addedToCartBtnLabel: 'Thank you!',
addingToCartBtnLabel: 'Adding...',
soldOutBtnLabel: 'Sold Out',
howLongTillBtnReturnsToNormal: 1000, // in milliseconds.
cartCountSelector: '#CartCount, .cart-count, #cart-count a:first, #gocart p a, #cart .checkout em, .item-count',
cartTotalSelector: '#cart-price',
// 'aboveForm' for top of add to cart form,
// 'belowForm' for below the add to cart form, and
// 'nextButton' for next to add to cart button.
feedbackPosition: 'nextButton',
// What you will never need to change
addToCartBtnSelector: '[type="submit"]',
addToCartFormSelector: 'form[action="/cart/add"]',
shopifyAjaxAddURL: '/cart/add.js',
shopifyAjaxCartURL: '/cart.js'
};
// We need some feedback when adding an item to the cart.
// Here it is.
var _showFeedback = function(success, html, $addToCartForm) {
$('.ajaxified-cart-feedback').remove();
var feedback = '<p class="ajaxified-cart-feedback ' + success + '">' + html + '</p>';
switch (_config.feedbackPosition) {
case 'aboveForm':
$addToCartForm.before(feedback);
break;
case 'belowForm':
$addToCartForm.after(feedback);
break;
case 'nextButton':
default:
$addToCartForm.find(_config.addToCartBtnSelector).after(feedback);
break;
}
// If you use animate.css
// $('.ajaxified-cart-feedback').addClass('animated bounceInDown');
$('.ajaxified-cart-feedback').slideDown();
};
var _setText = function($button, label) {
if ($button.children().length) {
$button.children().each(function() {
if ($.trim($(this).text()) !== '') {
$(this).text(label);
}
});
}
else {
$button.val(label).text(label);
}
};
var _init = function() {
$(document).ready(function() {
$(_config.addToCartFormSelector).submit(function(e) {
e.preventDefault();
var $addToCartForm = $(this);
var $addToCartBtn = $addToCartForm.find(_config.addToCartBtnSelector);
_setText($addToCartBtn, _config.addingToCartBtnLabel);
$addToCartBtn.addClass('disabled').prop('disabled', true);
// Add to cart.
$.ajax({
url: _config.shopifyAjaxAddURL,
dataType: 'json',
type: 'post',
data: $addToCartForm.serialize(),
success: function(itemData) {
// Re-enable add to cart button.
$addToCartBtn.addClass('inverted');
_setText($addToCartBtn, _config.addedToCartBtnLabel);
_showFeedback('success','<i class="fa fa-check"></i> Added to cart! <a href="/cart">View cart</a> or <a href="/collections/all">continue shopping</a>.',$addToCartForm);
window.setTimeout(function(){
$addToCartBtn.prop('disabled', false).removeClass('disabled').removeClass('inverted');
_setText($addToCartBtn,_config.addToCartBtnLabel);
}, _config.howLongTillBtnReturnsToNormal);
// Update cart count and show cart link.
$.getJSON(_config.shopifyAjaxCartURL, function(cart) {
if (_config.cartCountSelector && $(_config.cartCountSelector).size()) {
var value = $(_config.cartCountSelector).html() || '0';
$(_config.cartCountSelector).html(value.replace(/[0-9]+/,cart.item_count)).removeClass('hidden-count');
}
if (_config.cartTotalSelector && $(_config.cartTotalSelector).size()) {
if (typeof Currency !== 'undefined' && typeof Currency.moneyFormats !== 'undefined') {
var newCurrency = '';
if ($('[name="currencies"]').size()) {
newCurrency = $('[name="currencies"]').val();
}
else if ($('#currencies span.selected').size()) {
newCurrency = $('#currencies span.selected').attr('data-currency');
}
if (newCurrency) {
$(_config.cartTotalSelector).html('<span class=money>' + Shopify.formatMoney(Currency.convert(cart.total_price, "{{ shop.currency }}", newCurrency), Currency.money_format[newCurrency]) + '</span>');
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
}
}
else {
$(_config.cartTotalSelector).html(Shopify.formatMoney(cart.total_price, "{{ shop.money_format | remove: "'" | remove: '"' }}"));
}
};
});
},
error: function(XMLHttpRequest) {
var response = eval('(' + XMLHttpRequest.responseText + ')');
response = response.description;
if (response.slice(0,4) === 'All ') {
_showFeedback('error', response.replace('All 1 ', 'All '), $addToCartForm);
$addToCartBtn.prop('disabled', false);
_setText($addToCartBtn, _config.soldOutBtnLabel);
$addToCartBtn.prop('disabled',true);
}
else {
_showFeedback('error', '<i class="fa fa-warning"></i> ' + response, $addToCartForm);
$addToCartBtn.prop('disabled', false).removeClass('disabled');
_setText($addToCartBtn, _config.addToCartBtnLabel);
}
}
});
return false;
});
});
};
return {
init: function(params) {
// Configuration
params = params || {};
// Merging with defaults.
$.extend(_config, params);
// Action
$(function() {
_init();
});
},
getConfig: function() {
return _config;
}
}
})(jQuery);
Shopify.AjaxifyCart.init();
</script>
{% comment %}
If you want to animate your feedback message.
{% endcomment %}
{% comment %}
{{ '//cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.0/animate.min.css' | stylesheet_tag }}
{% endcomment %}
{{ '//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css' | stylesheet_tag }}
<style>
.ajaxified-cart-feedback {
display: block;
line-height: 36px;
font-size: 90%;
vertical-align: middle;
}
.ajaxified-cart-feedback.success {
color: #3D9970;
}
.ajaxified-cart-feedback.error {
color: #FF4136;
}
.ajaxified-cart-feedback a {
border-bottom: 1px solid;
}
</style>
我想知道是否有一个简单的解决方案。我不知所措。我会把它作为一个新问题,但在这一点上它看起来确实像一个 "two parter",因为它涉及到我分享的所有信息。
再次感谢您的宝贵时间
干杯!
theme.js 中的这行代码 'id="{{ product.variants.first.id }}"' 与您在任何 .js 文件中添加的代码 issue.When 完全一致,它不会在液体中呈现,但会将其呈现为细绳。 Theme.js 是一个简单的 .js 文件,不是液体,所以这条液体线将呈现为字符串。您需要更改该行,您的问题将得到解决。 您只需要将整个 theme.js.
中的“{{ product.variants.first.id }}”替换为 "val.variants[0].id"