手把手教你使用JS编写一个购物车界面
作者:正追军梦
前言
今天我们来剖析一个精心设计的家具商店购物车页面,这个页面不仅美观大方,还具备丰富的交互功能。让我们一步步拆解它的设计理念和技术实现!
页面展示
页面整体结构
这个购物车页面采用了经典的电商布局模式:
<!DOCTYPE html> <html> <head> <!-- 元信息和样式 --> </head> <body> <header>...</header> <div class="banner">...</div> <div class="container">...</div> <footer>...</footer> </body> </html>
这种结构清晰明了,用户一眼就能理解页面的组成。就像走进一家实体店一样:招牌(header)、促销海报(banner)、商品展示区(container)和出口信息(footer)。
设计亮点分析
1. 优雅的色彩方案
使用了紫色和金色作为主色调,既显高贵又不失现代感:
:root { --primary-purple: #673ab7; --secondary-gold: #d4af37; --dark-bg: #1a1a2e; --light-bg: #f8f9fa; }
紫色代表奢华,金色象征品质,完美契合家具商店的定位。这种配色方案就像为页面穿上了"高级定制西装"!
2. 响应式设计
页面在多种设备上都能完美展示:
@media (max-width: 768px) { .cart-container { grid-template-columns: 1fr; } /* 其他移动端优化 */ }
在小屏幕上,购物车布局会自动调整为单列,确保在手机上也能轻松操作。这就像把家具店"缩小"放进用户口袋!
3. 精美的横幅设计
顶部横幅采用了巧妙的CSS技巧:
.banner::before { content: ""; position: absolute; /* 渐变和斜线图案 */ background: linear-gradient(135deg, transparent 0%, transparent 50%, var(--dark-bg) 50%), repeating-linear-gradient(-45deg, var(--secondary-gold), var(--secondary-gold) 5px, transparent 5px, transparent 10px); }
这种设计创造出类似高档家具包装纸的纹理效果,视觉上既专业又精致。
购物车功能实现
1. 商品展示与操作
每个商品项都包含详细信息和控制元素:
<div class="cart-item" data-id="1" data-price="165.00"> <div class="item-details">...</div> <div class="item-price">$165.00</div> <div class="quantity-control"> <button class="quantity-btn minus">-</button> <input type="number" class="quantity-input" value="1" min="1"> <button class="quantity-btn plus">+</button> </div> <div class="item-subtotal"> $<span class="item-total">165.00</span> <button class="remove-btn"><i class="fas fa-trash"></i></button> </div> </div>
2. 动态计算逻辑
JavaScript负责所有计算逻辑:
// 更新购物车总价 function updateCartTotals() { const subtotal = cart.items.reduce((total, item) => { return total + (item.price * item.quantity); }, 0); const shippingCost = parseFloat(shippingOption.dataset.cost); const total = subtotal + shippingCost - cart.couponValue; cartSubtotal.textContent = subtotal.toFixed(2); cartTotal.textContent = total.toFixed(2); }
这种实现方式确保价格计算实时准确,就像有个"数学天才"在后台默默工作!
3. 交互反馈
当用户移除商品时,有平滑的动画效果:
itemElement.style.opacity = '0'; setTimeout(() => { itemElement.remove(); updateCartCount(); }, 300);
这种细节处理让用户操作有明确的视觉反馈,就像商品真的被"移出"购物车一样。
用户体验优化
1. 空购物车状态
当购物车清空时,页面会显示友好的提示:
<div class="empty-cart"> <h3>Your cart is empty</h3> <p>Add items to continue shopping</p> <button class="continue-btn">START SHOPPING</button> </div>
这避免了用户面对空白页面的困惑,就像店员友好地提醒:“您的购物车空啦,看看新品吧!”
2. 运费选项
提供多种运费选择,默认选中免费选项:
<div class="shipping-option"> <input type="radio" id="free-shipping" name="shipping" value="free-shipping" data-cost="0" checked> <label for="free-shipping">Free Shipping</label> </div>
这种设计既符合商业策略(鼓励用户达到免邮门槛),又提升了用户体验。
页面实现的全部代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Shopping Cart - Furniture Store</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="external nofollow" > <style> :root { --primary-purple: #673ab7; --secondary-gold: #d4af37; --dark-bg: #1a1a2e; --light-bg: #f8f9fa; --text-dark: #333; --text-light: #fff; --success: #28a745; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f5f5f5; color: var(--text-dark); line-height: 1.6; } /* Header Styles */ header { background-color: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.1); position: sticky; top: 0; z-index: 100; } .top-nav { background-color: var(--dark-bg); padding: 0.5rem 0; text-align: center; color: var(--text-light); font-size: 0.9rem; } .top-nav p { margin: 0; } .main-nav { display: flex; justify-content: space-between; align-items: center; padding: 1rem 5%; } .logo { color: var(--primary-purple); font-weight: bold; font-size: 1.8rem; text-decoration: none; } .search-bar { flex-grow: 1; margin: 0 2rem; } .search-bar input { width: 100%; padding: 0.7rem 1rem; border: 1px solid #ddd; border-radius: 50px; font-size: 0.95rem; } .nav-icons { display: flex; gap: 1.5rem; } .nav-icons a { color: var(--text-dark); text-decoration: none; font-size: 1.2rem; position: relative; } .nav-icons .cart-icon span { background-color: var(--primary-purple); color: white; font-size: 0.7rem; position: absolute; top: -8px; right: -8px; width: 18px; height: 18px; border-radius: 50%; display: flex; justify-content: center; align-items: center; } /* Banner Styles */ .banner { background: linear-gradient(rgba(26, 26, 46, 0.9), rgba(26, 26, 46, 0.9)), url('https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?auto=format&fit=crop&w=1350&q=80'); background-size: cover; background-position: center; padding: 2.5rem; color: white; text-align: center; position: relative; margin-bottom: 3rem; } .banner::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, transparent 0%, transparent 50%, var(--dark-bg) 50%), repeating-linear-gradient(-45deg, var(--secondary-gold), var(--secondary-gold) 5px, transparent 5px, transparent 10px); background-size: 200% 200%, cover; opacity: 0.1; } .banner h1 { font-size: 2.5rem; margin-bottom: 0.5rem; position: relative; z-index: 2; } .banner p { font-size: 1.1rem; opacity: 0.9; max-width: 600px; margin: 0 auto; position: relative; z-index: 2; } /* Main Content */ .container { max-width: 1200px; margin: 0 auto; padding: 0 2rem; } .cart-container { display: grid; grid-template-columns: 2fr 1fr; gap: 2rem; margin-bottom: 3rem; } @media (max-width: 768px) { .cart-container { grid-template-columns: 1fr; } } .cart-items { background: white; border-radius: 8px; box-shadow: 0 5px 15px rgba(0,0,0,0.05); overflow: hidden; } .cart-header { display: grid; grid-template-columns: 3fr 1fr 1fr 1fr; padding: 1rem 1.5rem; background-color: var(--light-bg); font-weight: bold; border-bottom: 1px solid #eee; } .cart-item { display: grid; grid-template-columns: 3fr 1fr 1fr 1fr; align-items: center; padding: 1.5rem; border-bottom: 1px solid #eee; } .item-details { display: flex; align-items: center; } .item-image { width: 80px; height: 80px; border-radius: 5px; overflow: hidden; margin-right: 1rem; background-color: #f5f5f5; } .item-image img { width: 100%; height: 100%; object-fit: cover; } .item-info h3 { font-size: 1.1rem; margin-bottom: 0.3rem; } .item-info p { color: #666; font-size: 0.95rem; } .item-price, .item-subtotal { font-weight: 600; color: var(--text-dark); } .quantity-control { display: flex; align-items: center; } .quantity-btn { width: 28px; height: 28px; border: 1px solid #ddd; background: none; border-radius: 4px; cursor: pointer; font-size: 1rem; display: flex; justify-content: center; align-items: center; } .quantity-input { width: 45px; text-align: center; border: 1px solid #ddd; margin: 0 8px; padding: 4px; border-radius: 4px; font-size: 1rem; } .remove-btn { background: none; border: none; color: #999; cursor: pointer; transition: color 0.3s; font-size: 0.9rem; display: flex; align-items: center; margin-left: 10px; } .remove-btn:hover { color: #ff5252; } .remove-btn i { margin-right: 5px; } /* Cart Summary */ .cart-summary { background: white; border-radius: 8px; box-shadow: 0 5px 15px rgba(0,0,0,0.05); padding: 1.5rem; height: fit-content; } .cart-summary h2 { font-size: 1.4rem; margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid #eee; } .summary-row { display: flex; justify-content: space-between; margin-bottom: 1rem; padding: 0.5rem 0; } .total-row { font-weight: bold; font-size: 1.1rem; padding-top: 1rem; border-top: 1px solid #eee; margin-top: 0.5rem; } .coupon-section { margin: 1.5rem 0; } .coupon-section h3 { font-size: 1.1rem; margin-bottom: 0.5rem; color: #555; } .coupon-input { display: flex; gap: 0.5rem; } .coupon-input input { flex-grow: 1; padding: 0.7rem 1rem; border: 1px solid #ddd; border-radius: 4px; font-size: 0.95rem; } .coupon-input button { background: var(--dark-bg); color: white; border: none; border-radius: 4px; padding: 0 1.5rem; cursor: pointer; transition: background 0.3s; } .coupon-input button:hover { background: #333; } .shipping-section { margin-bottom: 1.5rem; } .shipping-section h3 { font-size: 1.1rem; margin-bottom: 0.5rem; color: #555; } .shipping-options { border: 1px solid #eee; border-radius: 4px; padding: 0.5rem; } .shipping-option { margin-bottom: 0.5rem; } .shipping-option:last-child { margin-bottom: 0; } .checkout-btn { width: 100%; padding: 1rem; background-color: var(--primary-purple); color: white; border: none; border-radius: 4px; font-size: 1.1rem; font-weight: 600; cursor: pointer; transition: background-color 0.3s; display: flex; justify-content: center; align-items: center; gap: 0.5rem; } .checkout-btn:hover { background-color: #5833a0; } /* Cart Actions */ .cart-actions { display: flex; justify-content: space-between; padding: 1.5rem; background: white; border-top: 1px solid #eee; } .action-btn { padding: 0.7rem 1.5rem; border-radius: 4px; cursor: pointer; font-weight: 600; transition: all 0.3s; } .update-btn { background-color: var(--dark-bg); color: white; border: none; } .update-btn:hover { background-color: #333; } .continue-btn { background: none; border: 1px solid #ddd; color: var(--text-dark); } .continue-btn:hover { background-color: #f8f8f8; border-color: #ccc; } /* Footer */ footer { background-color: var(--dark-bg); color: var(--text-light); padding: 3rem 0 1.5rem; margin-top: 3rem; } .footer-content { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2rem; max-width: 1200px; margin: 0 auto; padding: 0 2rem; } .footer-column h3 { margin-bottom: 1.2rem; position: relative; padding-bottom: 0.5rem; } .footer-column h3::after { content: ""; position: absolute; bottom: 0; left: 0; width: 50px; height: 2px; background-color: var(--secondary-gold); } .footer-column p, .footer-column a { color: #aaa; font-size: 0.95rem; margin-bottom: 0.5rem; text-decoration: none; transition: color 0.3s; } .footer-column a:hover { color: white; } .copyright { text-align: center; padding-top: 2rem; color: #777; font-size: 0.9rem; } /* Responsive adjustments */ @media (max-width: 992px) { .footer-content { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 768px) { .main-nav { flex-wrap: wrap; } .logo { order: 1; } .search-bar { order: 3; width: 100%; margin: 1rem 0 0; } .nav-icons { order: 2; } .cart-header, .cart-item { grid-template-columns: 1fr; gap: 1rem; } .cart-header { display: none; } .item-details { margin-bottom: 1rem; } .item-price, .quantity-control, .item-subtotal { display: flex; justify-content: space-between; align-items: center; width: 100%; padding: 0.5rem 0; border-bottom: 1px solid #eee; } .cart-actions { flex-direction: column; gap: 1rem; } .action-btn { width: 100%; text-align: center; } } </style> </head> <body> <header> <div class="top-nav"> <p>FREE SHIPPING ON ORDERS OVER $99</p> </div> <nav class="main-nav"> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="logo">B</a> <div class="search-bar"> <input type="text" placeholder="Search here..."> </div> <div class="nav-icons"> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><i class="fas fa-user"></i></a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><i class="fas fa-heart"></i></a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="cart-icon"> <i class="fas fa-shopping-cart"></i> <span id="cart-count">2</span> </a> </div> </nav> </header> <div class="banner"> <h1>SHOPPING CART</h1> <p>Review your order before proceeding to checkout</p> </div> <div class="container"> <div class="cart-container"> <div class="cart-items"> <div class="cart-header"> <div>PRODUCT</div> <div>PRICE</div> <div>QUANTITY</div> <div>TOTAL</div> </div> <div class="cart-item" data-id="1" data-price="165.00"> <div class="item-details"> <div class="item-image"> <img src="https://images.unsplash.com/photo-1519947486511-46149fa0a254?auto=format&fit=crop&w=500&h=500&q=80" alt="Modern Chair"> </div> <div class="item-info"> <h3>Vestibulum suscipit</h3> <p>Modern Chair Design</p> </div> </div> <div class="item-price">$<span class="item-base-price">165.00</span></div> <div class="quantity-control"> <button class="quantity-btn minus">-</button> <input type="number" class="quantity-input" value="1" min="1"> <button class="quantity-btn plus">+</button> </div> <div class="item-subtotal"> $<span class="item-total">165.00</span> <button class="remove-btn"><i class="fas fa-trash"></i></button> </div> </div> <div class="cart-item" data-id="2" data-price="50.00"> <div class="item-details"> <div class="item-image"> <img src="data:image/jpeg;base64,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 " alt="Designer Lamp"> </div> <div class="item-info"> <h3>Vestibulum dictum magna</h3> <p>Designer Lamp</p> </div> </div> <div class="item-price">$<span class="item-base-price">50.00</span></div> <div class="quantity-control"> <button class="quantity-btn minus">-</button> <input type="number" class="quantity-input" value="1" min="1"> <button class="quantity-btn plus">+</button> </div> <div class="item-subtotal"> $<span class="item-total">50.00</span> <button class="remove-btn"><i class="fas fa-trash"></i></button> </div> </div> <div class="cart-actions"> <button class="action-btn update-btn">UPDATE CART</button> <button class="action-btn continue-btn">CONTINUE SHOPPING</button> </div> </div> <div class="cart-summary"> <h2>CART SUMMARY</h2> <div class="summary-row"> <div>SUBTOTAL</div> <div>$<span id="cart-subtotal">215.00</span></div> </div> <div class="summary-row"> <div>SHIPPING</div> <div id="shipping-cost">Calculated at next step</div> </div> <div class="summary-row total-row"> <div>TOTAL</div> <div>$<span id="cart-total">215.00</span></div> </div> <div class="coupon-section"> <h3>COUPON</h3> <p>Enter your coupon code if you have one.</p> <div class="coupon-input"> <input type="text" placeholder="Coupon code"> <button>APPLY</button> </div> </div> <div class="shipping-section"> <h3>SHIPPING OPTIONS</h3> <div class="shipping-options"> <div class="shipping-option"> <input type="radio" id="flat-rate" name="shipping" value="flat-rate" data-cost="7.00"> <label for="flat-rate">Flat Rate: $7.00</label> </div> <div class="shipping-option"> <input type="radio" id="free-shipping" name="shipping" value="free-shipping" data-cost="0" checked> <label for="free-shipping">Free Shipping</label> </div> </div> <p style="font-size: 0.9rem; margin-top: 0.5rem; color: #888;">Calculate Shipping</p> </div> <button class="checkout-btn"> PROCEED TO CHECKOUT <i class="fas fa-arrow-right"></i> </button> </div> </div> </div> <footer> <div class="footer-content"> <div class="footer-column"> <h3>CATEGORIES</h3> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Seating</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Table</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Workstation Furniture</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Dining Room</a> </div> <div class="footer-column"> <h3>INFORMATION</h3> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >About Us</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Shipping Policy</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Returns & Refunds</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Privacy Policy</a> </div> <div class="footer-column"> <h3>MY ACCOUNT</h3> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Sign In</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >View Cart</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >My Wishlist</a> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Track My Order</a> </div> <div class="footer-column"> <h3>CONTACT</h3> <p>123 Design Street</p> <p>Furniture City, FC 10001</p> <p>Phone: (123) 456-7890</p> <p>Email: info@furniturestore.com</p> </div> </div> <div class="copyright"> <p>© 2023 Furniture Store. All Rights Reserved.</p> </div> </footer> <script> document.addEventListener('DOMContentLoaded', function() { // 初始化购物车状态 const cart = { items: [ { id: '1', name: 'Vestibulum suscipit', price: 165.00, quantity: 1 }, { id: '2', name: 'Vestibulum dictum magna', price: 50.00, quantity: 1 } ], shippingCost: 0, couponValue: 0 }; // DOM元素缓存 const cartItemsContainer = document.querySelector('.cart-items'); const cartSubtotal = document.getElementById('cart-subtotal'); const cartTotal = document.getElementById('cart-total'); const shippingCostDisplay = document.getElementById('shipping-cost'); const cartCount = document.getElementById('cart-count'); // 初始化UI updateCartCount(); updateCartTotals(); // 数量控制事件委托 cartItemsContainer.addEventListener('click', function(e) { const target = e.target; // 加号按钮 if (target.classList.contains('plus')) { const input = target.parentElement.querySelector('.quantity-input'); input.value = parseInt(input.value) + 1; updateItemQuantity(input); } // 减号按钮 if (target.classList.contains('minus')) { const input = target.parentElement.querySelector('.quantity-input'); if (parseInt(input.value) > 1) { input.value = parseInt(input.value) - 1; updateItemQuantity(input); } } // 移除按钮 if (target.closest('.remove-btn')) { const itemElement = target.closest('.cart-item'); const itemId = itemElement.dataset.id; // 从购物车移除 cart.items = cart.items.filter(item => item.id !== itemId); updateCartTotals(); // 移除UI元素 itemElement.style.opacity = '0'; setTimeout(() => { itemElement.remove(); updateCartCount(); // 如果购物车为空,显示空状态 if (cart.items.length === 0) { cartItemsContainer.innerHTML = ` <div class="empty-cart" style="padding: 2rem; text-align: center;"> <h3>Your cart is empty</h3> <p style="margin: 1rem 0;">Add items to continue shopping</p> <button class="continue-btn" style="margin-top: 1rem;">START SHOPPING</button> </div> `; } }, 300); } }); // 输入框数量变化监听 cartItemsContainer.addEventListener('input', function(e) { if (e.target.classList.contains('quantity-input')) { const input = e.target; if (input.value < 1) input.value = 1; updateItemQuantity(input); } }); // 更新单个商品数量 function updateItemQuantity(input) { const itemElement = input.closest('.cart-item'); const itemId = itemElement.dataset.id; const quantity = parseInt(input.value); // 更新购物车数据 const item = cart.items.find(item => item.id === itemId); if (item) { item.quantity = quantity; // 更新小计显示 const itemTotalEl = itemElement.querySelector('.item-total'); if (itemTotalEl) { itemTotalEl.textContent = (item.price * quantity).toFixed(2); } updateCartTotals(); } } // 更新购物车总价 function updateCartTotals() { // 计算小计 const subtotal = cart.items.reduce((total, item) => { return total + (item.price * item.quantity); }, 0); // 获取运费选项 const shippingOption = document.querySelector('input[name="shipping"]:checked'); const shippingCost = parseFloat(shippingOption.dataset.cost); // 计算总价 const total = subtotal + shippingCost - cart.couponValue; // 更新UI cartSubtotal.textContent = subtotal.toFixed(2); cartTotal.textContent = total.toFixed(2); shippingCostDisplay.textContent = shippingCost === 0 ? 'Calculated at next step' : `$${shippingCost.toFixed(2)}`; // 更新右上角购物车数量 updateCartCount(); } // 更新购物车数量显示 function updateCartCount() { const itemCount = cart.items.reduce((count, item) => { return count + item.quantity; }, 0); cartCount.textContent = itemCount; } // 运费选项变更监听 const shippingOptions = document.querySelectorAll('input[name="shipping"]'); shippingOptions.forEach(option => { option.addEventListener('change', updateCartTotals); }); // 更新购物车按钮 const updateBtn = document.querySelector('.update-btn'); if (updateBtn) { updateBtn.addEventListener('click', function() { alert('Your cart has been updated!'); }); } }); </script> </body> </html>
总结
这个购物车页面实现了:
- 美观的设计:精心挑选的配色和布局
- 完善的功能:商品管理、价格计算、优惠券应用
- 优秀的用户体验:响应式设计、交互动画、空状态处理
- 清晰的代码结构:模块化CSS和JavaScript
通过这个案例,我们可以看到现代电商页面如何将设计美学与实用功能完美结合。下次你设计购物车时,不妨参考这些思路,让你的用户享受"逛高端家具店"般的购物体验!
到此这篇关于使用JS编写一个购物车界面的文章就介绍到这了,更多相关JS编写购物车界面内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!