简介:这是一套高仿主流APP的H5手机端商城静态页面合集,面向前端初学者与求职者,用于快速掌握移动端电商类页面的结构组织、交互逻辑与响应式布局实践。资源包含34个功能完整页面,覆盖首页、商品分类、详情、购物车、订单管理、用户中心、登录注册、收货地址维护及提现流程等核心模块,全部采用纯HTML/CSS/JS实现,无后端依赖,适合离线学习与二次开发。压缩包共133个文件,含34个HTML页面、11个JS脚本(含jQuery插件调用)、3个CSS样式表及72个PNG图标资源,辅以少量JPG图、字体文件(eot/woff/ttf/svg),整体仅2.02MB,轻量易解压。已有1226人学习下载,代码手写为主、结构清晰、命名规范,配合sweetalert、mmenu等轻量插件实现弹窗与侧边栏交互,是理解H5商城前端分层设计与静态资源协同的优质参考样本。
1. H5商城.zip:一个能直接扔进Nginx跑起来的手机端商城静态包,适合快速验证UI逻辑、做原型联调、甚至当离线演示素材
你有没有遇到过这种场景:产品刚画完高保真原型,前端还没开工,但销售明天就要给客户现场演示一个“能点、能跳、能加购”的手机端商城?或者测试同学想在没后端环境时,先手动测一遍购物车跳转路径和商品列表渲染逻辑?又或者你正带新人练手,需要一个结构清晰、无框架黑盒、所有代码一眼可见的H5商城参考?这个H5商城.zip就是为这类「立刻要、不求全、重可读、零依赖」的硬需求而生的。它不是Vue/React工程,没有webpack配置、没有API代理、没有登录态管理——它就是纯HTML+CSS+JavaScript组成的静态页面集合,所有资源内联或本地引用,解压后双击index.html就能在浏览器里打开,扔进Nginx根目录就能用http://localhost访问。它不解决高并发、不处理支付回调、不对接用户中心,但它把「商品列表→详情→加入购物车→购物车结算→订单确认」这条核心链路,用最直白的DOM操作和localStorage模拟,完整走通了五遍。适合UI工程师核对动效、测试同学构造边界用例、前端新人理解页面跳转本质,也适合嵌入到企业微信/钉钉微应用中作为轻量级服务入口。
2. 解构H5商城.zip:从文件树到核心交互逻辑,看懂它为什么能“开箱即用”
2.1 文件结构与技术栈定位:为什么说它是“纯前端静态页面”?
解压后你会看到一个极简的目录结构:
H5商城/ ├── index.html # 首页:商品分类+轮播+推荐列表 ├── product-list.html # 商品列表页(支持分类筛选) ├── product-detail.html # 商品详情页(含规格选择、数量增减) ├── cart.html # 购物车页(增删改查+合计计算) ├── order-confirm.html # 订单确认页(收货地址+支付方式模拟) ├── assets/ │ ├── css/ │ │ └── style.css # 全局样式,含rem适配、flex布局、图标字体 │ ├── js/ │ │ ├── utils.js # 工具函数:getURLParam、formatPrice、debounce │ │ ├── cart-manager.js # 购物车核心:add/remove/update/calculate │ │ └── main.js # 页面级初始化:轮播初始化、事件绑定、数据加载 │ └── images/ # 所有图片资源(png/jpg/svg),无CDN外链 └── data/ └── mock-data.json # 模拟商品/分类/地址数据,JSON格式,无请求提示:整个包不含任何
.vue、.ts、.jsx文件,不依赖Node.js环境,package.json和node_modules完全不存在。所有JS逻辑均使用ES5语法编写,兼容Android 4.4+、iOS 8+的WebView。style.css中font-size: 100px配合<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">实现rem响应式,这是它能在不同手机上“看起来像原生App”的底层保障。
2.2 核心交互链路:从点击商品到生成订单号,每一步都落在localStorage上
整个商城的“状态持久化”只依赖localStorage,这是它脱离后端的关键设计。我们以“用户将商品A加入购物车”为例,拆解真实执行流:
// cart-manager.js 中 addCartItem 函数节选 function addCartItem(item) { const cart = JSON.parse(localStorage.getItem('cart') || '[]'); const existing = cart.find(i => i.id === item.id && i.sku === item.sku); if (existing) { existing.quantity += item.quantity || 1; } else { cart.push({ id: item.id, sku: item.sku || 'default', name: item.name, price: item.price, image: item.image, quantity: item.quantity || 1 }); } localStorage.setItem('cart', JSON.stringify(cart)); updateCartBadge(); // 同步更新顶部购物车角标 }这段代码说明三件事:
- 数据来源:
item对象由product-detail.html中点击“加入购物车”按钮时,通过>{ "categories": [ {"id": "1", "name": "手机数码", "icon": "icon-phone"}, {"id": "2", "name": "家用电器", "icon": "icon-appliance"} ], "products": [ { "id": "1001", "name": "旗舰智能手机X1", "price": 2999, "image": "assets/images/phone-x1.jpg", "category_id": "1", "specs": [{"name": "颜色", "options": ["星空黑", "极光银"]}, {"name": "内存", "options": ["128GB", "256GB"]}], "description": "搭载最新处理器..." } ], "addresses": [ { "id": "addr-001", "name": "张三", "phone": "138****1234", "address": "XX市XX区XX路1号", "is_default": true } ] }关键设计点在于:
- 分类与商品强关联:
product.category_id对应categories.id,product-list.html通过URL参数?category=1过滤商品; - 规格可扩展:
specs数组支持任意层级组合,product-detail.html中动态渲染多级下拉,选择后生成唯一sku(如1001-black-128g); - 地址复用:
order-confirm.html直接读取addresses数组渲染收货地址列表,点击设为默认即更新is_default字段并同步localStorage。
这种结构让五页之间通过
localStorage和URL参数松耦合通信,避免了全局状态管理库的引入,也降低了新人理解成本——你看得见数据在哪、怎么来、怎么变。3. 快速上手:三步部署,五秒验证,让H5商城在本地真正跑起来
3.1 环境准备:不需要Node、不需要Python,只要一个浏览器和一个文件管理器
你不需要安装任何开发工具。
H5商城.zip的设计哲学就是“最小依赖”。验证它是否可用,只需三步:- 解压:右键
H5商城.zip→ “解压到H5商城/”; - 双击:进入解压后的
H5商城/文件夹,直接双击index.html; - 观察:浏览器自动打开首页,检查轮播图是否自动切换、商品列表是否正常渲染、点击商品能否跳转到详情页。
如果这三步成功,说明你的浏览器(Chrome/Firefox/Safari/Edge)完全兼容该包。若失败(如空白页、报错
Uncaught ReferenceError),大概率是浏览器禁用了file://协议下的localStorage(常见于Safari隐私模式),此时请跳至3.2节用简易HTTP服务启动。注意:不要试图用VS Code的Live Server插件打开——它会注入额外脚本,可能干扰
localStorage读写。务必用系统默认浏览器双击,或用3.2节方案。3.2 本地HTTP服务启动:用Python或Nginx绕过file://限制
当双击
index.html失效时(尤其在Safari或某些企业版Chrome中),你需要一个真正的HTTP服务。这里提供两种零配置方案:方案一:Python内置HTTP服务(推荐给无Nginx经验者)
确保已安装Python 3.x(命令行输入
python --version确认),然后在H5商城/目录下执行:# Windows/Linux/macOS通用 python -m http.server 8000执行后终端会显示
Serving HTTP on 0.0.0.0 port 8000,此时打开浏览器访问http://localhost:8000即可。所有页面跳转、购物车增减、订单提交全部正常工作。python -m http.server是Python标准库模块,无需额外安装,且默认允许localStorage读写。方案二:Nginx一键托管(推荐给已有Nginx的用户)
将
H5商城/整个文件夹复制到Nginx的html/目录下(如/usr/local/nginx/html/h5-mall/),然后修改Nginx配置:# nginx.conf 中 server 块内添加 location /h5-mall/ { alias /usr/local/nginx/html/h5-mall/; index index.html; # 关键:允许跨域字体加载(因css中用了iconfont) add_header Access-Control-Allow-Origin *; }重启Nginx后访问
http://localhost/h5-mall/。此方案优势在于:可直接复用生产Nginx配置(如gzip压缩、缓存头),且能真实模拟线上静态资源托管环境。3.3 核心功能验证清单:五页逐项测试,确认无逻辑断点
不要只点首页轮播就认为“跑起来了”。请按以下顺序手动验证,每步耗时不超过30秒:
页面 操作步骤 预期结果 验证目的 index.html点击顶部“手机数码”分类tab URL变为 product-list.html?category=1,列表只显示手机类商品测试URL参数路由与分类过滤 product-list.html点击任一商品卡片 跳转至 product-detail.html?id=1001,页面显示正确商品信息测试商品ID透传与详情加载 product-detail.html选择“颜色:星空黑”+“内存:256GB”,点击“加入购物车” 右上角购物车角标数字+1,控制台无报错 测试规格组合生成SKU与localStorage写入 cart.html进入后修改某商品数量为0 → 点击“删除” 该商品从列表消失,角标数字同步更新 测试购物车实时计算与DOM更新 order-confirm.html点击“提交订单” 弹出提示“订单提交成功,订单号:ORDabc123”, localStorage.orders新增一条记录测试订单快照生成与持久化 血泪经验:曾有同事在
product-detail.html中误删了<script src="assets/js/cart-manager.js">标签,导致“加入购物车”按钮完全无响应,但页面其他功能正常。这种错误不会报错,只会静默失效——所以必须逐页验证,不能只信首页。4. 避坑指南:五个真实踩过的坑,省下你两小时调试时间
4.1 现象:点击商品跳转后,详情页显示“商品不存在”,控制台报
Cannot read property 'name' of undefined原因:
product-detail.html通过URL参数id查找mock-data.json中的商品,但mock-data.json里该id对应的商品对象被误删或ID类型不匹配(如JSON中是字符串"1001",而JS中用数字1001查找)。
解决:打开product-detail.html,找到const productId = getURLParam('id');这一行,在其下方加一行console.log('查找ID:', productId, '数据中ID:', data.products[0].id);,对比类型与值。确保mock-data.json中所有id字段均为字符串,并在JS中统一用String(productId)转换后再查找。4.2 现象:购物车角标数字不更新,或更新延迟半秒以上
原因:
cart-manager.js中updateCartBadge()函数被多次重复绑定。常见于main.js中未做防重绑定,每次页面跳转都重新执行document.addEventListener('DOMContentLoaded', init),导致updateCartBadge()被注册N次。
解决:在cart-manager.js顶部声明一个全局锁变量let badgeUpdateLock = false;,修改updateCartBadge()为:function updateCartBadge() { if (badgeUpdateLock) return; badgeUpdateLock = true; const cart = JSON.parse(localStorage.getItem('cart') || '[]'); const count = cart.reduce((sum, item) => sum + item.quantity, 0); document.querySelector('.cart-badge').textContent = count || ''; setTimeout(() => { badgeUpdateLock = false; }, 100); // 防抖释放锁 }4.3 现象:iOS Safari中,轮播图无法自动播放,手动滑动后卡死
原因:iOS Safari对
setTimeout在页面非活跃状态(如切到其他Tab)下的执行有严格限制,utils.js中轮播的autoPlayInterval未做页面可见性检测。
解决:在轮播初始化代码中加入document.hidden监听:let autoPlayTimer; function startAutoPlay() { if (document.hidden) return; // 页面不可见时暂停 autoPlayTimer = setInterval(nextSlide, 3000); } document.addEventListener('visibilitychange', () => { if (document.hidden) { clearInterval(autoPlayTimer); } else { startAutoPlay(); } });4.4 现象:在微信内置浏览器中,点击“提交订单”后无反应,控制台报
localStorage is not available原因:微信iOS版在某些版本中,对
file://协议或特定域名下的localStorage有更严策略,但根本原因是order-confirm.html中提交按钮的onclick事件被微信的WeixinJSBridge拦截。
解决:将内联onclick改为事件委托,并在main.js中统一处理:// 删除 order-confirm.html 中 <button onclick="submitOrder()"> 的 onclick 属性 document.getElementById('submit-order-btn').addEventListener('click', function(e) { e.preventDefault(); submitOrder(); });同时确保
submitOrder()函数末尾有return false;,避免事件冒泡。4.5 现象:修改
mock-data.json后,页面数据未更新,仍显示旧商品原因:浏览器强缓存了
data/mock-data.json,尤其是Chrome对.json文件缓存策略激进,默认不检查Last-Modified。
解决:在main.js中加载数据时强制添加时间戳参数:// 原代码:fetch('data/mock-data.json') // 改为: const timestamp = new Date().getTime(); fetch(`data/mock-data.json?t=${timestamp}`) .then(r => r.json()) .then(data => { /* 处理数据 */ });或更彻底——在Nginx配置中为
.json文件禁用缓存:location ~ \.json$ { add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; }5. 进阶改造:三个可立即落地的定制化技巧,让H5商城真正为你所用
5.1 技巧一:用正则批量替换商品图片路径,十分钟接入自有CDN
项目中所有图片路径形如
assets/images/phone-x1.jpg,但你的CDN域名是https://cdn.example.com/mall/。手动改几十个<img src>太傻。打开VS Code,按Ctrl+H(Windows)或Cmd+H(macOS),启用正则模式(.*图标),输入:Find: (src|href)="assets/images/(.+?\.(?:png|jpg|jpeg|gif|svg))" Replace: $1="https://cdn.example.com/mall/$2"点击“全部替换”,
index.html、product-detail.html等所有文件中的图片路径瞬间更新。关键点:$1保留原始属性名(src或href),$2捕获文件名,避免误替换了CSS中的background-image路径。替换后记得清空浏览器缓存(Ctrl+Shift+R),否则仍加载旧图。5.2 技巧二:为购物车增加价格区间筛选,三行代码搞定
当前购物车页只显示所有商品,但运营常需“查看100元以下商品”。打开
cart.html,在购物车列表上方添加筛选控件:<!-- 在 <div class="cart-list"> 上方插入 --> <div class="price-filter"> <label>价格区间:</label> <select id="price-range"> <option value="all">全部</option> <option value="0-100">0-100元</option> <option value="100-500">100-500元</option> <option value="500+">500元以上</option> </select> </div>然后在
cart-manager.js末尾追加筛选逻辑:document.getElementById('price-range').addEventListener('change', function() { const range = this.value; const cart = JSON.parse(localStorage.getItem('cart') || '[]'); let filtered = cart; if (range !== 'all') { const [min, max] = range.split('-').map(Number); filtered = cart.filter(item => { const price = parseFloat(item.price); if (range.endsWith('+')) return price >= min; return price >= min && price <= max; }); } renderCartList(filtered); // 假设你已有 renderCartList 函数 });玄学提醒:
parseFloat(item.price)必须加,因为mock-data.json中price是数字,但localStorage序列化后变成字符串,不转会导致"2999" >= 100返回true(字符串比较),实际应为数值比较。5.3 技巧三:导出购物车数据为Excel,支持线下核对与邮件发送
测试同学常需把当前购物车内容导出为Excel发给产品确认。
H5商城.zip本身无后端,但可借助前端库SheetJS(xlsx.js)实现。下载https://cdn.sheetjs.com/xlsx-0.20.2/package/dist/xlsx.full.min.js,放入assets/js/目录,然后在cart.html底部<script>前添加:<script src="assets/js/xlsx.full.min.js"></script> <script> function exportCartToExcel() { const cart = JSON.parse(localStorage.getItem('cart') || '[]'); const ws_data = [ ['商品ID', '名称', '单价(元)', '数量', '小计(元)'] ].concat( cart.map(item => [ item.id, item.name, parseFloat(item.price).toFixed(2), item.quantity, (parseFloat(item.price) * item.quantity).toFixed(2) ]) ); const ws = XLSX.utils.aoa_to_sheet(ws_data); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "购物车"); XLSX.writeFile(wb, `购物车_${new Date().toISOString().slice(0,10)}.xlsx`); } </script> <!-- 在购物车页添加按钮 --> <button onclick="exportCartToExcel()" class="btn-export">导出Excel</button>点击按钮即生成
购物车_2024-06-15.xlsx,双击可直接用Excel打开。注意:此功能在Safari中需用户主动点击触发(不能自动下载),符合浏览器安全策略。从那以后我每次接手新H5项目,都会先解压一个
H5商城.zip,把它当成“前端乐高底板”——缺轮播就抄index.html里的,缺规格选择就扒product-detail.html的DOM结构,连购物车计算逻辑都直接ctrl+c/v进自己项目再微调。它不炫技、不造轮子、不卷框架,就老老实实把一件事做透:让一个商城的核心流程,在纯静态环境下,稳稳地跑起来。希望帮到你。本文还有配套的精品资源,点击获取
- 分类与商品强关联: