期末大作业年年有,但“HTML+CSS+JavaScript购物商城”这个题目几乎快被写烂了。我每年都能看到一批学生交上来的作业长一个样:白底、蓝色链接、表格布局、商品图是百度搜的、点击“加入购物车”没反应、刷新一下购物车全没了。说实话,这种作业老师看得想打瞌睡,分数自然不会高。
但我也见过有人用同样的题目拿到全班最高分。差别不在功能多不多,而在三个东西:页面看起来是否像一个真的商城、交互逻辑是否闭环、代码结构是否经得起老师随口一问。这篇文章就把我总结的一套“期末大作业级购物商城”完整方案拆给你看,从页面规划到核心代码,从布局技巧到答辩常问的问题,全部给出可以直接抄的答案和必须理解的原理。
先说结论:这个作业想拿高分,不需要后端、不需要框架,甚至不需要一行PHP或数据库。纯HTML+CSS+JavaScript完全够用,关键看你怎么组织代码、怎么把交互做完整,以及能不能在答辩的时候把设计思路说清楚。
1. 动手写代码之前,先把商城“画”出来
很多同学拿到题就打开编辑器开始敲,敲到哪算哪,最后页面乱七八糟。我建议你先花一晚上干件事:用纸或任意绘图工具把商城长什么样画出来。这个环节直接决定你后面是顺风顺水还是处处返工。
1.1 页面清单:一个完整的商城需要哪些页面
一个标准购物商城,最低限度需要这么几个页面:
- 首页(index.html):商品列表 + 推荐位 + 导航栏
- 商品详情页(detail.html):单件商品的大图、价格、描述、加购按钮
- 购物车页(cart.html):已加购商品清单、数量修改、总价计算、结账按钮
- 结算确认页(checkout.html):模拟填写收货信息并确认订单
期末大作业不建议再做登录页、注册页,除非你的题目明确要求。原因很简单:登录注册页面做出来之后,你势必要处理“登录态”的问题,这在纯前端里只能用localStorage模拟,而一旦模拟登录,你就得写大量业务逻辑,白白消耗时间,答辩时还可能被老师追问“密码存在哪、安不安全”,自己给自己挖坑。商城本质是“逛、选、买”三步,页面越聚焦,完成度越高。
1.2 首页的模块划分
首页是整个作业的门面,老师打开浏览器第一眼看到的就是它。我的建议是首页从上到下分成五个区块:
- 顶部导航栏:Logo、搜索框、导航菜单(首页、全部商品、购物车图标带数字角标)
- 轮播图Banner:三到四张图自动切换,可以用JS控制,也可以用CSS动画
- 商品分类筛选区:用几个按钮(全部、手机数码、电脑办公、家用电器)切换商品列表
- 商品列表区:网格布局的商品卡片,每张卡片包含商品图、名称、价格、评价数、加购按钮
- 页脚区:版权信息、关于我们等占位文本
为什么首页要这么多区块?因为老师在验收作业时,会在前30秒内判断你的页面“像不像一个商城”。只要有导航栏、轮播图、筛选按钮、商品卡片这几个视觉锚点,哪怕细节糙一点,第一印象分就已经拿到了。
1.3 目录结构提前规划好
不要把所有文件堆在一个文件夹里。我推荐这种结构:
code复制shopping-mall/
├── index.html // 首页
├── detail.html // 商品详情页
├── cart.html // 购物车页
├── checkout.html // 结算页
├── css/
│ ├── common.css // 全局公共样式
│ ├── index.css // 首页单独样式
│ ├── detail.css // 详情页样式
│ └── cart.css // 购物车样式
├── js/
│ ├── data.js // 模拟商品数据
│ ├── utils.js // 公共工具函数
│ ├── cart.js // 购物车逻辑(全局共用)
│ ├── index.js // 首页交互
│ ├── detail.js // 详情页交互
│ └── cart-page.js // 购物车页面交互
└── images/ // 本地图片
这种拆分方式在答辩时非常加分。老师问“你们的项目结构是怎么组织的”,你可以直接说出每个文件负责什么,这体现的是工程化思维,而大多数学生只会把代码全塞进一个文件里。哪怕你的代码量完全一样,不同的组织方式在老师眼中的档次完全不同。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. HTML语义化:骨架打扎实,后面才能站得稳
HTML是整个商城的骨架。很多同学喜欢满屏div,但语义化标签既能让代码更可读,也是期末作业的一个隐性加分项。老师一眼扫过去看到section、article、aside,就知道你平时是真看了点规范。
2.1 首页HTML骨架和要点
以首页为例,核心结构建议这样写:
html复制<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>品鲜商城 - 首页</title>
<link rel="stylesheet" href="css/common.css">
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<!-- 顶部导航栏 -->
<header class="site-header">
<div class="container header-inner">
<div class="logo">
<a href="index.html">品鲜商城</a>
</div>
<form class="search-box" id="searchForm">
<input type="text" placeholder="搜索商品" id="searchInput">
<button type="submit">搜索</button>
</form>
<nav class="main-nav">
<ul>
<li><a href="index.html" class="active">首页</a></li>
<li><a href="#product-list">全部商品</a></li>
<li><a href="cart.html" id="cartLink">购物车(<span id="cartCount">0</span>)</a></li>
</ul>
</nav>
</div>
</header>
<!-- 轮播图 -->
<section class="banner" id="banner">
<div class="banner-slides" id="bannerSlides">
<div class="slide active"><img src="images/banner1.jpg" alt="促销活动1"></div>
<div class="slide"><img src="images/banner2.jpg" alt="促销活动2"></div>
<div class="slide"><img src="images/banner3.jpg" alt="促销活动3"></div>
</div>
<button class="banner-prev" id="bannerPrev">❮</button>
<button class="banner-next" id="bannerNext">❯</button>
<div class="banner-dots" id="bannerDots"></div>
</section>
<!-- 商品列表 -->
<section class="product-section" id="product-list">
<div class="container">
<div class="section-title">
<h2>全部商品</h2>
<div class="filter-btns" id="filterBtns">
<button class="filter-btn active" data-category="all">全部</button>
<button class="filter-btn" data-category="phone">手机数码</button>
<button class="filter-btn" data-category="computer">电脑办公</button>
<button class="filter-btn" data-category="appliance">家用电器</button>
</div>
</div>
<div class="product-grid" id="productGrid">
<!-- 商品卡片由JS动态渲染 -->
</div>
</div>
</section>
<!-- 页脚 -->
<footer class="site-footer">
<div class="container">
<p>品鲜商城 期末大作业项目</p>
<p>仅供学习交流使用</p>
</div>
</footer>
<script src="js/data.js"></script>
<script src="js/utils.js"></script>
<script src="js/cart.js"></script>
<script src="js/index.js"></script>
</body>
</html>
这里有几个细节值得说:
第一,商品列表区用空的div占位,由JavaScript从数据文件里动态生成卡片。这样做的好处是数据和页面分离,老师问到你数据从哪来,你直接指data.js。而且以后想改商品内容,只需改数据文件,不需要动HTML。
第二,导航栏的购物车角标是一个span标签,id叫cartCount,这为后面JS统一更新购物车数量预留了挂载点。
第三,搜索框用的是form标签而不是单纯的div,因为form支持在输入框里按回车就触发提交。需要注意阻止表单默认提交行为,否则页面会刷新导致状态
