代码实现Shopify 单个订单限制最多加8件商品的
最近估计被批发的看上了,老是有人一下子买10件+的商品,这样导致物流成本过高,而且金额超过后免邮了,划不来。
所以怎么样可以限制用户只能一个订单购买不超过8件商品呢?
同个修改代码,不使用付费插件来实现这个功能:
这个代码做了以下动作:
- 使用更通用的选择器 – 尝试多种可能的元素选择器来匹配购物车项目和结账按钮
- 改进事件监听 – 包含更多的事件类型和Shopify特定事件
- 更好的错误处理 – 更可靠的DOM元素查找
- 更全面的监听 – 包括输入事件、表单提交、DOM变化等
- 异步延迟 – 确保页面元素完全加载后才执行检查
将此代码添加到 layout/theme.liquid 文件中,在 </body> 标签之前,替换之前的代码。
<!-- START CUSTOM CART SKU LIMIT CODE -->
<!-- This code prevents customers from checking out if they have more than 8 items in cart -->
<script>
// 增强版本 - 使用更通用的选择器和事件监听
(function() {
'use strict';
function initCartSkuLimit() {
// 检查购物车项总数
function checkCartItemCount() {
let totalItems = 0;
// 尝试多种选择器来获取购物车项目
const selectors = [
'.cart-item input[name*="updates"]',
'.cart-items input[name*="updates"]',
'input[name*="updates"]',
'.quantity__input',
'[data-cart-quantity]'
];
for (let i = 0; i < selectors.length; i++) {
const quantityInputs = document.querySelectorAll(selectors[i]);
if (quantityInputs.length > 0) {
quantityInputs.forEach(function(input) {
const quantity = parseInt(input.value) || 1;
totalItems += quantity;
});
break;
}
}
return totalItems;
}
// 显示错误消息
function showErrorMessage(message) {
// 移除现有的错误消息
const existingError = document.querySelector('.cart-sku-limit-error');
if (existingError) {
existingError.remove();
}
// 创建新的错误消息
const errorMessage = document.createElement('div');
errorMessage.className = 'cart-sku-limit-error';
errorMessage.style.cssText = `
background-color: #f8d7da;
color: #721c24;
padding: 15px;
margin: 15px 0;
border: 1px solid #f5c6cb;
border-radius: 4px;
text-align: center;
font-weight: bold;
font-size: 16px;
z-index: 9999;
`;
errorMessage.textContent = message;
// 添加到购物车表单顶部
const cartForm = document.querySelector('form[action^="/cart"]') ||
document.querySelector('form[action="/cart/update.js"]') ||
document.querySelector('.cart__contents form') ||
document.querySelector('form[method="post"]');
if (cartForm) {
cartForm.parentNode.insertBefore(errorMessage, cartForm);
} else {
// 如果找不到表单,就添加到主要内容区域
const mainContent = document.querySelector('#MainContent') || document.querySelector('main');
if (mainContent) {
mainContent.insertBefore(errorMessage, mainContent.firstChild);
}
}
}
// 隐藏错误消息
function hideErrorMessage() {
const existingError = document.querySelector('.cart-sku-limit-error');
if (existingError) {
existingError.remove();
}
}
// 检查并应用限制
function applySkuLimit() {
const totalItems = checkCartItemCount();
// 尝试多种选择器来获取结账按钮
const checkoutSelectors = [
'button[name="checkout"]',
'.cart__checkout-button',
'[data-cart-checkout]',
'input[type="submit"][name="checkout"]',
'.button--primary[name="checkout"]',
'.cart-checkout-button'
];
let checkoutButton = null;
for (let i = 0; i < checkoutSelectors.length; i++) {
checkoutButton = document.querySelector(checkoutSelectors[i]);
if (checkoutButton) break;
}
if (totalItems > 8) {
if (checkoutButton) {
checkoutButton.disabled = true;
checkoutButton.style.opacity = '0.5';
checkoutButton.style.cursor = 'not-allowed';
checkoutButton.setAttribute('title', 'Maximum 8 pairs of glasses per order');
}
showErrorMessage('Maximum 8 pairs of glasses per order.');
// 阻止所有结账相关的点击事件
preventCheckoutNavigation();
} else {
if (checkoutButton) {
checkoutButton.disabled = false;
checkoutButton.style.opacity = '1';
checkoutButton.style.cursor = 'pointer';
checkoutButton.removeAttribute('title');
}
hideErrorMessage();
}
}
// 阻止结账导航
function preventCheckoutNavigation() {
// 阻止结账按钮点击
const checkoutButtons = document.querySelectorAll('button[name="checkout"], [data-cart-checkout], .cart__checkout-button');
checkoutButtons.forEach(button => {
button.addEventListener('click', function(e) {
if (checkCartItemCount() > 8) {
e.preventDefault();
e.stopPropagation();
showErrorMessage('Maximum 8 pairs of glasses per order.');
return false;
}
}, true);
});
// 阻止结账链接点击
const checkoutLinks = document.querySelectorAll('a[href="/checkout"], a[href*="checkout"]');
checkoutLinks.forEach(link => {
link.addEventListener('click', function(e) {
if (window.location.pathname.includes('/cart') && checkCartItemCount() > 8) {
e.preventDefault();
e.stopPropagation();
showErrorMessage('Maximum 8 pairs of glasses per order.');
return false;
}
}, true);
});
}
// 页面加载完成后执行
function onPageReady() {
if (window.location.pathname.includes('/cart')) {
// 等待页面完全加载后再执行
setTimeout(() => {
applySkuLimit();
}, 500);
}
}
// 监听购物车数量变化
function setupQuantityListeners() {
// 使用事件委托监听所有数量输入变化
document.addEventListener('change', function(e) {
if (e.target.matches('input[name*="updates"], .quantity__input, [data-cart-quantity]')) {
setTimeout(() => {
if (window.location.pathname.includes('/cart')) {
applySkuLimit();
}
}, 100);
}
});
// 监听输入事件(实时更新)
document.addEventListener('input', function(e) {
if (e.target.matches('input[name*="updates"], .quantity__input, [data-cart-quantity]')) {
setTimeout(() => {
if (window.location.pathname.includes('/cart')) {
applySkuLimit();
}
}, 300);
}
});
// 监听表单提交(更新购物车)
document.addEventListener('submit', function(e) {
if (e.target.matches('form[action^="/cart"]')) {
setTimeout(() => {
if (window.location.pathname.includes('/cart')) {
applySkuLimit();
}
}, 500);
}
});
}
// 设置MutationObserver来监听DOM变化
function setupDomObserver() {
const observer = new MutationObserver(function(mutations) {
let shouldCheck = false;
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' || mutation.type === 'attributes') {
// 检查是否有购物车相关元素发生变化
if (mutation.target.closest('.cart') ||
mutation.target.matches('.cart, [data-cart-contents], .cart-items') ||
Array.from(mutation.addedNodes).some(node =>
node.nodeType === 1 &&
(node.classList.contains('cart') ||
node.classList.contains('cart-item') ||
node.matches('input[name*="updates"]'))
)) {
shouldCheck = true;
}
}
});
if (shouldCheck && window.location.pathname.includes('/cart')) {
setTimeout(() => {
applySkuLimit();
}, 300);
}
});
// 开始观察整个body的变化
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['value', 'class']
});
}
// 初始化
onPageReady();
setupQuantityListeners();
setupDomObserver();
// 监听Shopify特定事件
document.addEventListener('shopify:section:load', function() {
if (window.location.pathname.includes('/cart')) {
setTimeout(() => {
applySkuLimit();
}, 300);
}
});
// 监听自定义购物车更新事件
document.addEventListener('cart-updated', function() {
if (window.location.pathname.includes('/cart')) {
setTimeout(() => {
applySkuLimit();
}, 300);
}
});
// 监听AJAX完成事件
document.addEventListener('ajaxComplete', function() {
if (window.location.pathname.includes('/cart')) {
setTimeout(() => {
applySkuLimit();
}, 300);
}
});
}
// 确保在DOM加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initCartSkuLimit);
} else {
initCartSkuLimit();
}
})();
</script>
<!-- END CUSTOM CART SKU LIMIT CODE -->
<!-- For questions about this code, search for "CUSTOM CART SKU LIMIT CODE" in your theme files -->
