纯HTML无法实现真正可用的购物车,必须结合CSS构建语义化结构(如带data-属性的<li>)、JavaScript处理交互与状态(事件委托、localStorage同步)及精度计算。
纯 HTML 无法实现真正可用的购物车——它没有状态存储、不能增删商品、不响应用户操作。所谓“HTML 购物车页面布局”,本质是用 HTML + CSS 搭建静态结构,再靠 JavaScript 驱动交互。直接写一堆 <div> 堆出购物车样子,但点不了“加减”、算不了总价、关掉页面就清空,这种不是购物车,是截图素材。
核心是语义化与可扩展性。别用 <table> 做布局(语义错、响应式难),也别全塞 <div class="item">(缺乏数据关联)。推荐用带 data- 属性的 <li> 或 <article> 包裹单个商品:
<ul id="cart-list"> <li data-id="1024" data-price="299.00"> <h3>无线降噪耳机</h3> <span class="price">¥<span>299.00</span></span> <div class="quantity"> <button type="button" data-action="decrease">−</button> <span>1</span> <button type="button" data-action="increase">+</button> </div> </li></ul>
data-id 和 data-price 是后续 JS 计算和同步的关键,别等写 JS 时再补<button> 而非 <input type="number">:前者更易绑定事件、防非法输入、兼容老浏览器<span id="cart-total">,不要塞在列表里重复计算常见做法是 JS 里用字符串拼 <li>...</li> 再 innerHTML 插入,问题集中爆发在三处:
"<li data-id='"+id+"'" 这种写法遇到商品名含单引号(如 O'Reilly)直接破坏 DOM 结构name 或 price 来自用户输入或后端未转义,innerHTML 会执行其中的 <script>
querySelectorAll 再遍历 addEventListener,代码臃肿正确姿势是用 document.createElement + textContent(防 XSS)+ 事件委托(在 #cart-list 上监听 click,判断 event.target.dataset.action)。
立即学习“前端免费学习笔记(深入)”;
很多人存完 JSON.stringify(cartArray) 就以为完了,但实际刷新页面后发现数量归零或商品消失,原因往往是:
localStorage.setItem('cart', JSON.stringify(cartArray)) —— 只在页面加载时读,不写,等于白存localStorage.cart = cartArray,结果存的是 [object Object] 字符串,取出来是废数据0.1 + 0.2 === 0.30000000000000004,显示总价时要用 parseFloat((a + b).toFixed(2)) 或 Intl.NumberFormat
建议封装一个 saveCart() 函数,在所有修改逻辑末尾统一调用,避免遗漏。
购物车真正的复杂点不在布局,而在状态同步:本地存、接口同步、库存校验、优惠叠加、跨设备一致性……HTML 页面布局只是最表层的一张皮,皮底下没 JS 骨架和数据逻辑,它连“能用”都算不上。