news 2026/9/14 1:41:26

多页面网站前端实战:以南昌地铁官网20个页面为例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多页面网站前端实战:以南昌地铁官网20个页面为例

简介:面向大学生与前端初学者的企业官网网页设计成品,以南昌地铁为主题,完整实现20个页面,涵盖HTML5结构、CSS3样式与JavaScript交互,适用于HTML5期末作业、Web前端课程设计及企业官网实战练习。压缩包共170个文件,包含20个HTML页面、13个CSS样式表、15个JS脚本,以及大量jpg/png/jpeg图片素材、SVG图标、字体、GIF、MP4和说明文档,整体约54.42MB,目录结构清晰,便于直接部署与二次修改。页面涉及首页、线路导览、票价查询等模块,包含轮播图、下拉菜单、响应式布局等常见交互,价值在于提供一套可直接运行的企业官网完整方案,帮助初学者理解多页面站点的信息架构、样式组织与脚本配合。已有210人学习使用,适合需要快速完成期末作品或想学习整站开发流程的人群。

1. 20 个页面的“期末作业”,真正的考点是资源组织

提到“南昌地铁官网 20 个页面”,很多人第一反应是页面多、工作量大。但真正动手做过的人都知道,20 个静态页面最耗时间的不是页面数量,而是页面之间如何共用同一套样式、如何让轮播和日期选择这类第三方组件不互相打架、如何在 375px 到 1440px 的宽度范围里不出横向滚动条。这个基于 HTML5 + CSS3 + JavaScript 的地铁官网,技术上没有复杂后端,却把前端入门阶段该碰的问题都踩了一遍:第三方 CSS 文件的加载顺序、公共导航的复用、页面级样式隔离、插件初始化时机。不管是为了完成大学生期末作业,还是想把 web 前端多页面网页制作的基本功补齐,照着这套结构拆一遍,比单独做几个单页要有效得多。

2. 从 style.css 到 nouislider.css:拆开压缩包看技术选型

拿到压缩包,先不要急着双击index.html。把 CSS 文件列表过一遍,会发现这套资源几乎是一个“标准企业官网前端工具链”:style.css、hover-min.css、animate.css、font-awesome.min.css、bootstrap-datepicker.min.css、responsive.css、bootstrap-select.min.css、magnific-popup.css、owl.carousel.min.css、nouislider.css。光看文件名,就能判断出项目里用了日期选择器、下拉选择、Magnific Popup 弹窗、Owl Carousel 轮播和 noUiSlider 滑块。这些并不是装饰,而是官网“时刻表查询”“票价区间筛选”“车站实景图放大”这些功能的实现基础。

2.1 先看 CSS 加载顺序:层叠从 head 里就开始

CSS 的层叠规则是“后面的覆盖前面的”,所以 head 里的引入顺序决定最终渲染效果。这是 html 网页制作里最容易被忽略的一环。常见做法是先放工具类和插件样式,再放项目自定义样式,确保自己的规则能盖住第三方默认样式。

<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>南昌地铁 - 首页</title> <!-- 第三方图标与动画 --> <link rel="stylesheet" href="css/font-awesome.min.css"> <link rel="stylesheet" href="css/animate.css"> <!-- 第三方插件样式 --> <link rel="stylesheet" href="css/owl.carousel.min.css"> <link rel="stylesheet" href="css/magnific-popup.css"> <link rel="stylesheet" href="css/bootstrap-select.min.css"> <link rel="stylesheet" href="css/bootstrap-datepicker.min.css"> <link rel="stylesheet" href="css/nouislider.css"> <!-- 本项目自定义样式 --> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/hover-min.css"> <link rel="stylesheet" href="css/responsive.css"> </head>

这段代码的逻辑是:Font Awesome 图标字体和 animate.css 动画类要最先可用,因为后面所有 HTML 结构里都可能引用它们;插件样式按“容器优先”的顺序排;最后加载 style.css、hover-min.css 和 responsive.css。.min.css后缀代表压缩版本,删掉了换行和空格,加载体积更小。学习阶段为了能看懂源码,可以换成未压缩版本,部署时再换回 min 文件。

2.2 每个文件的职责与选型理由

把 10 个 CSS 文件按职责分一下类,就得到一份“多页面官网样式资产表”。

文件类型承担的功能典型页面
style.css项目自定义全站布局、卡片、导航、配色全部页面
hover-min.css微交互按钮和卡片鼠标移入时的动效服务介绍、首页
animate.css入场动画元素滚动出现时的淡入和上移首页、关于我们
font-awesome.min.css图标字体菜单、按钮、功能区图标全部页面
bootstrap-datepicker.min.css表单插件乘车日期选择控件出行助手
responsive.css项目自定义不同屏幕宽度下的适配修正全部页面
bootstrap-select.min.css表单插件线路下拉搜索框的样式线路查询
magnific-popup.css弹窗插件车站实景图放大查看站点详情
owl.carousel.min.css轮播插件首页大图和新闻推荐滑动首页、资讯
nouislider.css滑块插件票价区间筛选票价查询

这里要注意,bootstrap-datepicker 和 bootstrap-select 本身依赖 Bootstrap 的栅格和表单基础样式,但如果压缩包里的 style.css 已经把这些基础样式合并起来了,head 里就不需要单独再引一份 bootstrap.min.css。判断方法很简单:在浏览器里打开任意一个带下拉框的页面,看样式是否错位。错位就说明 style.css 顶部缺少 Bootstrap 核心样式,需要补上。

2.3 为什么不自己写这些插件

不少同学做作业喜欢“纯手写”,但在 20 个页面的规模下,时间应该优先花在信息结构和响应式上。Owl Carousel 的触屏滑动和回弹效果,手写至少几百行 JS 才能稳定复现;Magnific Popup 处理了 ESC 关闭、焦点回退、图片预加载这些细节;noUiSlider 在触摸端两个手柄不重叠的处理也很成熟。直接使用这些经过生产环境验证的组件,是企业在做 web 前端时更常见的做法,也是这个项目里最值得学习的一点:不要重复造轮子,把每个插件放在正确的场景里。

2.4 hover-min.css 与“css 鼠标移入事件”

“css 鼠标移入事件”是初学者经常搜索的说法,但 CSS 里没有事件,只有:hover伪类。hover-min.css 是 Hover.css 的压缩版,它提供了一批现成的类名,比如.hvr-sweep-to-right.hvr-underline-from-left,加到元素上就能产生扫过、下划线生长等效果。其实现和手写伪元素类似。

.hvr-sweep-to-right { position: relative; overflow: hidden; } .hvr-sweep-to-right::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.06); transform: scaleX(0); transform-origin: left; transition: transform 0.3s ease-out; } .hvr-sweep-to-right:hover::before { transform: scaleX(1); }

hvr-sweep-to-right类加到导航按钮或卡片上,鼠标移入时就会有一个从左向右扫过的蒙层。注意.hvr-sweep-to-right本身要设position: relative,否则伪元素会脱离到页面左上角。用这个文件比在 style.css 里逐个写:hover要省事,但对完全没看过源码的人,出了问题不好排查,所以至少要理解这类类名背后的结构。

3. 20 个页面不写 20 份导航:公共头尾复用与样式隔离

多页面网站的导航和页脚如果靠复制粘贴,改一次全站链接要打开 20 个文件重来一遍,几乎等于灾难。处理思路是把 header 和 footer 抽成独立片段,页面里只留一个占位标记,加载完成后再把片段填进去。这个方案不依赖后端,用纯 JavaScript 就能实现,也可以在写完所有页面前先搭好框架,后续新增页面成本很低。

3.1 用 include.js 把 header 和 footer 变成可复用模块

在项目根目录建一个components文件夹,存放header.htmlfooter.html。header 里放完整的导航结构,页面里只需要一行引用。

<!-- index.html --> <body> <header>document.addEventListener("DOMContentLoaded", function () { var includes = document.querySelectorAll("[data-include]"); includes.forEach(function (el) { var file = el.getAttribute("data-include"); fetch(file) .then(function (res) { if (!res.ok) { throw new Error(file + " 加载失败"); } return res.text(); }) .then(function (html) { el.innerHTML = html; }) .catch(function (err) { console.warn("公共头部/底部加载失败:", err); }); }); });

这段逻辑是:页面 DOM 解析完成后,遍历所有带有><!-- index.html --> <body>document.addEventListener("DOMContentLoaded", function () { var currentPage = document.body.getAttribute("data-page"); var navLinks = document.querySelectorAll(".main-nav a"); navLinks.forEach(function (link) { if (link.getAttribute("data-page") === currentPage) { link.classList.add("current"); } }); });

>/* 票价查询页自己的覆盖 */ .page-fare .panel { border-color: #2b6cb0; } .page-fare .price-range { margin: 24px 0 8px; } /* 线路列表页特殊缩进 */ .page-line-list .station-item { padding-left: 32px; }

把覆盖范围限制在.page-fare.page-line-list作用域内,能避免页面之间的样式污染。这样写还有一个好处:以后想单独调整某个页面的间距或配色,不需要去全局样式里加一堆条件注释,直接在对应作用域里改即可。

3.4 给 CSS 和 JS 加版本号,避免缓存干扰

多页面网站最常见的“改了 CSS 不生效”问题,大部分是浏览器缓存导致。常见做法是给静态资源加查询参数,例如:

<link rel="stylesheet" href="css/style.css?v=20260120"> <script src="js/main.js?v=20260120"></script>

加版本号的原理是浏览器的 URL 变化会使缓存失效。每次发布前更新v参数,就能强制用户拿到新样式。对于项目作业,至少要在开发阶段理解这个机制,否则后面调整复试样式时容易误判成代码问题。

4. 把轮播、弹窗、日期选择、下拉和范围滑块的初始化串起来

20 个页面的交互看起来分散,但本质上都是一套初始化流程。这个项目里除了 noUiSlider 以外,Owl Carousel、Magnific Popup、Bootstrap Datepicker、Bootstrap Select 都依赖 jQuery。如果在 main.js 里没有先确保 jQuery 已加载,控制台会立刻报$ is not defined。所以 script 标签的引入顺序也应该遵循“jQuery 再插件再项目脚本”的规则。

4.1 整合初始化代码:main.js 的模块化写法

我一般会在js/main.js里集中管理所有插件,不把初始化代码散落在各个页面。这样可以减少重复代码,排查问题时也只要看一个文件。

(function () { function ready(fn) { if (document.readyState !== "loading") { fn(); } else { document.addEventListener("DOMContentLoaded", fn); } } ready(function () { // 1. 首页轮播 if (document.querySelector(".owl-carousel")) { $(".owl-carousel").owlCarousel({ items: 1, loop: true, autoplay: true, autoplaySpeed: 800, nav: true, navText: [ "<i class='fa fa-angle-left'></i>", "<i class='fa fa-angle-right'></i>" ], dots: true, responsive: { 768: { items: 2 }, 1200: { items: 3 } } }); } // 2. 车站图片弹窗 $(".popup-gallery").magnificPopup({ delegate: "a", type: "image", gallery: { enabled: true }, closeOnContentClick: true }); // 3. 乘车日期选择 $(".take-date").datepicker({ format: "yyyy-mm-dd", todayHighlight: true, autoclose: true }); // 4. 线路下拉搜索 $(".select-line").selectpicker({ noneSelectedText: "请选择线路", liveSearch: true, size: 8 }); // 5. 票价区间滑块 var slider = document.getElementById("fare-slider"); if (slider && window.noUiSlider) { noUiSlider.create(slider, { start: [2, 8], connect: true, step: 1, range: { min: 2, max: 13 } }); slider.noUiSlider.on("update", function (values) { document.getElementById("fare-range").textContent = values[0] + " 元 - " + values[1] + " 元"; }); } }); })();

这段代码的核心思路是:用ready函数模拟document.ready的兼容处理,再逐个判断页面中是否存在对应容器,存在才初始化对应插件。每个插件前加 DOM 判断,不仅能避免无关页面多执行无意义的初始化,还能防止容器不存在时插件报错导致后续 JS 中断。navText里使用 Font Awesome 图标替代默认文字箭头,是官网视觉统一时比较顺手的方法。

4.2 插件参数怎么改:重点参数对照

很多初学 JavaScript 的同学拿到一段初始化代码能运行,但不知道怎么改成自己需要的效果。这里把常用参数单独列出来。

插件常用参数作用与调整思路
owlCarouselitems / loop / autoplay / navTextitems 控制每屏数量,loop 设为 false 时第一张不能往前循环
owlCarouselresponsive按断点覆盖 items,适合首页多栏目卡片轮播
magnificPopupdelegate / gallery / typedelegate 必须指向实际触发弹窗的链接,type 决定用图片还是内联内容
datepickerformat / autoclose / todayHighlightformat 建议与后端接口要求的日期格式一致,避免提交时二次转换
selectpickerliveSearch / size / noneSelectedText超过 10 个站点建议开启 liveSearch,否则下拉太长
noUiSliderstart / connect / range / stepstart 是初始区间,connect 为 true 表示两端滑块之间的区域填充颜色

调整参数时把值改掉,刷新页面就能看到效果。比如票价区间如果改成 2 到 15 元,只需要修改range里的max: 15,滑块末端位置会自动变化,start里的初始值也必须落在range范围内,否则滑块会被钳制到边界。

4.3 跨页面传条件:URL 参数替代 JS 全局变量

线路查询页和票价查询页都可能出现“选择条件后跳转到结果页面”的场景。如果直接在 JS 里定义变量,跳转后变量就丢失了,常见做法是把条件拼接到 URL 后面。

function goResult() { var line = $("#line-select").val(); var date = $(".take-date").val(); location.href = "result.html?line=" + encodeURIComponent(line) + "&date=" + encodeURIComponent(date); }

在 result.html 里再解析:

function getUrlParam(name) { var params = new URLSearchParams(location.search); return params.get(name); } var line = getUrlParam("line"); var date = getUrlParam("date"); if (line) { $("#result-hint").text("当前线路:" + line + ",乘车日期:" + date); }

encodeURIComponent的作用是把中文和特殊字符转成 URL 安全格式,避免?line=1号线&date=...中的中文导致解析错乱。URLSearchParams是现代浏览器内置的 URL 解析 API,比手写 split 处理要清晰得多。

4.4 JS 报错先看执行顺序

项目里最容易出现的三个错误是:$ is not defined$(...).owlCarousel is not a functionnoUiSlider is not defined。第一个是 jQuery 没加载或路径写错;第二个是插件 JS 文件被放在 jQuery 之前加载,导致插件没有注册到$.fn上;第三个是 nouislider 的 JS 文件没有引入,而 main.js 里又用到了window.noUiSlider。排查时打开开发者工具控制台,看第一条红色报错,再配合 Network 面板确认文件是否 404,通常几分钟就能定位。

5. 响应式断点、样式覆盖链和最后一道验证

这个项目的 responsive.css 不是独立重写整套布局,而是把 Bootstrap 风格断点下的“修正”集中放一起。20 个页面如果每个都在 style.css 里堆媒体查询,文件会越来越难维护,把响应式修正单独拆分出来是合理的设计。

5.1 responsive.css 的断点策略

常见做法是向上兼容为主,小屏修正为辅。

@media (min-width: 768px) { .page-home .banner-caption { top: 30%; } } @media (min-width: 992px) { .line-sidebar { position: sticky; top: 20px; } } @media (max-width: 767px) { .navbar-toggle { display: block; } .mobile-menu { overflow-x: auto; -webkit-overflow-scrolling: touch; } }

min-width写桌面增强,页面在 768px 以上的平板和桌面都能获得相同增强;用max-width写移动端专属修正。两种写法混用时要特别小心顺序,因为后面min-width可能会覆盖前面max-width里的相同属性。

5.2 常见响应式翻车现场

多页面官网最容易出现三个响应式问题。第一是轮播图在小屏下高度塌陷,Owl Carousel 多列模式下单张图片高度不一致,解决办法是给轮播图设置固定高度,并让图片按object-fit: cover裁剪。第二是 flex 布局中子项不收缩导致横向溢出,给子项加min-width: 0通常能解决。第三是 selectpicker 在窄屏下把下拉菜单撑到屏幕外,限制下拉面板宽度并开启liveSearch,可以明显减少误触。

5.3 验证响应式不能只靠拖动浏览器窗口

Chrome 开发者工具的 Device Toolbar 里预置了 Moto G4、iPhone SE、iPhone 12 Pro 等真实设备尺寸,逐个打开主要页面检查导航是否遮挡内容、页面是否存在横向滚动条。如果觉得逐个页面翻太慢,可以在控制台手动跑一段检查脚本。

document.querySelectorAll("*").forEach(function (el) { if (el.scrollWidth > document.documentElement.clientWidth) { console.warn("横向溢出元素:", el, el.scrollWidth); } });

这段代码的逻辑是遍历页面上所有元素,把元素的scrollWidth和视口宽度做对比。一旦某个元素内容超宽,就说明导致横向滚动条的根因在这里。这个脚本在开发阶段随时可以手动执行,不建议直接写进生产环境页面,避免影响用户性能。

5.4 看懂“是谁改了我的样式”

在票价查询页里如果想修改下拉框圆角,可能会遇到自己写的样式不生效。Chrome DevTools 的 Elements 面板右侧 Styles 列表会按优先级从高到低展示所有匹配规则,被划掉的就是被后面的规则覆盖掉的声明。解决顺序是:先确认style.css确实在插件 CSS 之后加载,再用更高优先级的选择器,例如.page-fare .dropdown-menu,而不是直接给规则加!important。只有理解了层叠和选择器特异性,才能真正控制 20 个页面里的每一处细节。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 1:40:31

计算机视觉数据标注工具:labelimg与labelme对比指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 1:40:22

SpringBoot实现企业级Wiki系统的RBAC权限管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 1:39:39

NiceGUI 可编辑 AG Grid 实战:构建支持增、删、改行的数据表格

NiceGUI 可编辑 AG Grid 实战&#xff1a;构建支持增、删、改行的数据表格 【免费下载链接】nicegui Create web-based user interfaces with Python. The nice way. 项目地址: https://gitcode.com/GitHub_Trending/ni/nicegui 导读 本指南以 NiceGUI 仓库中的 exampl…

作者头像 李华
网站建设 2026/9/14 1:39:16

SpringBoot驱动的微信小程序网络安全科普系统

简介&#xff1a;本资源是一套面向计算机专业本科生及毕业设计学生的全栈开发实战案例&#xff0c;聚焦微信小程序与SpringBoot协同架构的网络安全科普系统实现。项目覆盖前端小程序&#xff08;WXML/WXSS/JS&#xff09;、后端Java服务&#xff08;SpringBootMyBatisSpring Se…

作者头像 李华