用HTML+CSS+jQuery搭建音乐网站:AI项目实践的前端展示方案
发布时间:2026/9/15 2:47:28来源:尧图网络
简介这是一份面向前端入门及进阶学习者的音乐网站设计实战项目使用 HTML 搭建结构、CSS 控制样式、jQuery 实现动效与交互。项目包含完整网页源码与静态资源覆盖音乐列表、播放器界面、导航菜单等核心模块支持响应式布局并提供播放/暂停、音量调节、歌曲切换等常用功能适合希望锻炼前端综合开发能力、理解三者协同方式的人群也可作为人工智能方向人员补充 Web 前端基础的练习案例。包体共 99 个文件大小约 5.68MB其中 45 个 html 页面负责内容结构7 个 css 文件负责视觉样式2 个 js 脚本负责动态交互另有 33 张 jpg、5 张 png 图片及字体、图标等素材模块划分清晰方便按需阅读和二次开发。当前已有 90 人学习下载动手改造此项目可快速掌握静态页面搭建、样式美化与常用交互实现为进一步开发功能更完整的在线音乐平台打下基础。1. 用 HTML CSS jQuery 搭音乐站人工智能项目实践里最容易被低估的“最后一公里”打开人工智能-项目实践-html-音乐网站设计这类题目时很多人会疑惑人工智能在哪儿其实这类课程设计的真实目标是让 AI 方向的学生学会把模型输出、推荐结果或统计数据用一个能点、能听的界面呈现出来。HTML 负责内容骨架CSS 负责视觉与布局jQuery 负责交互响应三者合在一起就是一个完整可演示的前端作品。对新手来说它既能算人工智能大作业的展示层也可以当作独立的网页制作练习对熟手而言则是重新审视静态页面如何接数据、如何响应状态的好样本。本文按照从业者最常见的做法把这套方案讲透。2. 页面骨架与布局HTML 语义化与 CSS 栅格怎么排才不返工网页制作的第一步不是写代码而是把信息架构画出来。音乐网站无论简单与否页面里通常包含五类区域顶部导航Logo、搜索框、菜单入口、内容推荐位、歌曲列表、页脚以及悬浮在底部的播放条。用 HTML 写结构时我建议不要一上来就套 div而是按 HTML5 语义化标签划分区块这样后续用 CSS 调整布局时选择器能少写一半。2.1 先画信息架构音乐站必备的六个模块header.site-header ├─ div.logo站点标识可放一个音符图标 ├─ nav.main-nav热门推荐、歌单、排行榜三个入口 ├─ form.search-box关键词搜索 main.site-content ├─ section.hero-banner轮播推荐位展示热门专辑 ├─ section.hot-list热门歌曲列表由 jQuery 动态填充 ├─ section.artist-grid歌手/歌单卡片网格 footer.site-footer版权信息占位 div.player-bar固定底部的播放条这套结构里有两个容易踩的坑。第一个坑是 Logo 用h1还是div我一般把站点标题放进h1因为整站只有一个主标题时对 SEO 和读屏器都更友好第二个坑是轮播推荐位如果赶时间不必引入轮播插件用 CSS 渐变背景加一张封面图就能做出效果jQuery 只负责定时切换文案这一点在第 3 章会展开。2.2 HTML 骨架代码DOCTYPE、字符集与三块关键区任何网页文件的第一行都应该是!DOCTYPE html它不是普通标签而是文档模式声明。缺失这行时浏览器会进入怪异模式盒模型计算方式都会变CSS 里让input居中、宽度 100% 的写法全部会出现偏差。下面是可直接复制的骨架!DOCTYPE html html langzh-cn head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleAI 音乐电台/title link relstylesheet hrefcss/style.css /head body header classsite-header div classlogo h1a href#AI 音乐电台/a/h1 /div nav classmain-nav ul lia href# classactive热门推荐/a/li lia href#歌单/a/li lia href#排行榜/a/li /ul /nav form classsearch-box idsearchBox input typetext placeholder搜索歌曲或歌手 idsearchInput button typesubmit搜索/button /form /header main classsite-content section classhero-banner idheroBanner div classhero-text h2今日推荐Focus 歌单/h2 p适合深度工作的纯音乐氛围/p /div /section section classhot-list h2热门歌曲/h2 ul idsongList classsong-list/ul /section /main div classplayer-bar audio idplayer controls/audio div classplayer-info idplayerInfo未在播放/div /div script srcjs/jquery-3.6.0.min.js/script script srcjs/main.js/script /body /html这里需要说明几个细节viewport的content固定按widthdevice-width, initial-scale1.0写移动端打开页面时才不会自动缩放langzh-cn告诉浏览器和读屏器当前页面是简体中文朗读时会按中文音色处理audio标签加controls属性可以直接使用浏览器原生播放控件做课程演示时不必自己写进度条和音量条。歌曲列表ul先留空后续由 jQuery 根据 JSON 数据动态填充这样页面结构和数据是解耦的。2.3 三行模式的 CSS 文件变量、组件与页面层分开写很多课程作业的 CSS 写得又长又乱改一个主色调要找半天。我习惯用三行模式组织样式第一段是基础层负责重置盒模型和定义 CSS 变量第二段是组件层负责导航、按钮、播放条这些跨页面复用的部件第三段才是页面专属样式只放当前页面独有的间距和修饰。下面这段代码可以直接用于前面那份 HTML/* 基础层重置盒模型与默认边距定义全局变量 */ * { margin: 0; padding: 0; box-sizing: border-box; } :root { --bg-primary: #f5f6fa; --bg-dark: #1e1e2e; --accent: #ff6b6b; --text-main: #2f3542; --nav-height: 60px; } /* 组件层导航、按钮、播放条的公共样式 */ body { font-family: PingFang SC, Microsoft YaHei, sans-serif; background: var(--bg-primary); color: var(--text-main); } .site-header { position: fixed; top: 0; width: 100%; height: var(--nav-height); background: var(--bg-dark); display: flex; align-items: center; padding: 0 24px; z-index: 100; } /* 页面专属层内容区、Hero、播放条间距 */ .site-content { margin-top: var(--nav-height); padding: 24px; } .hero-banner { height: 220px; border-radius: 16px; background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; display: flex; align-items: center; padding: 24px; } .player-bar { position: fixed; bottom: 0; left: 0; right: 0; background: var(--bg-dark); display: flex; align-items: center; gap: 16px; padding: 12px 24px; color: #fff; }/* 补充导航内部元素垂直居中input 也能吃上 flex */ .site-header .search-box { display: flex; align-items: center; gap: 8px; } .site-header .search-box input { height: 36px; padding: 0 12px; border-radius: 18px; border: none; outline: none; }:root里定义的变量是整个主题的开关。后面想换背景色或强调色只改这一处即可。Flex 布局是这个项目的主力导航栏用display: flexalign-items: center让垂直居中一行搞定播放条用gap: 16px控制内部间距搜索框里的input也靠 flex 的 align-items 自然居中不需要传统的margin: 0 autohack。如果后面要加歌手网格推荐用 Grid.artist-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; }auto-fill会根据容器宽度自动排满每一行minmax(180px, 1fr)表示卡片最小 180px有空余空间时均匀拉伸这是响应式网格最省心的写法。常见颜色与间距的定义可参考下表后续换主题只改:root一处即可。变量名建议值用途--bg-primary#f5f6fa页面主背景--bg-dark#1e1e2e导航与播放条背景--accent#ff6b6b高亮、按钮主色--nav-height60px导航栏高度内容区 margin-top 用3. 交互层jQuery 把静态页面变成能点的音乐站骨架和样式搭完页面仍然只是静态展示。音乐网站必须有点得动的播放按钮、搜得到的列表、切换得过去的标签页。用原生 JavaScript 也能写但这门实践课指定了 jQuery一方面因为$(选择器)语法对新手友好另一方面展示播放状态、操作菜单这类交互jQuery 的链式调用能让代码量明显减少。3.1 播放控制audio 元素与 jQuery 的结合播放器部分是整个站点的核心交互。我用audio标签承载音频地址jQuery 只做三件事监听点击、切换播放/暂停、更新界面文案。先定义一个歌曲数组再实现点击切换// 歌曲数据真实场景会从 JSON 接口加载 var playlist [ { title: Focus Flow, artist: AI Composer, src: audio/track1.mp3 }, { title: Night Drive, artist: Neon Beats, src: audio/track2.mp3 }, { title: Chill Step, artist: Studio AI, src: audio/track3.mp3 } ]; var currentIndex 0; function loadTrack(index) { var track playlist[index]; $(#player).attr(src, track.src); // 设置 audio 的音频地址 $(#playerInfo).text(track.title - track.artist); currentIndex index; } $(#songList).on(click, .song-item, function() { var index $(this).data(index); // 从>$(#playBtn).on(click, function() { var player $(#player)[0]; if (player.paused) { player.play(); $(this).text(暂停); } else { player.pause(); $(this).text(播放); } });这个模式里用player.paused作为状态判断的来源而不是自己维护一个布尔变量。原因是浏览器可能因为音频加载失败、音频播放完毕等因素改变播放状态自己维护的变量会和实际状态脱节界面按钮文字就会出现显示播放但实际在唱着的错位。3.2 鼠标移入移出事件与轮播切换热门推荐位想加一点动效时CSS 的:hover能解决视觉反馈但需要改变多个兄弟元素的类名时还是要 jQuery 的mouseenter/mouseleave来配合。举一个播放条的例子歌曲信息默认单行省略鼠标移入后显示完整标题移出后恢复单行截断。$(.player-info).on(mouseenter, function() { $(this).css(white-space, normal); // 悬浮时允许换行 }).on(mouseleave, function() { $(this).css(white-space, nowrap); // 离开恢复单行 });mouseenter和mouseleave与 CSS 的:hover的差别在于它们不向子元素冒泡适合处理移入容器就算触发的场景。轮播推荐位时间紧张时可以用一个简单的setInterval来做定时切换var heroItems [歌单 A, 歌单 B, 歌单 C]; var heroIndex 0; setInterval(function() { heroIndex (heroIndex 1) % heroItems.length; $(#heroBanner h2).text(今日推荐 heroItems[heroIndex]); }, 3000);%取模运算让下标始终在 0 到 2 之间循环这是轮播最常用的写法。课程演示里setInterval已经足够正式上线时应该用setTimeout递归或 CSStransition做渐变避免快速切换时产生闪烁。3.3 不引 Bootstrap用 jQuery 模拟静态下拉菜单课程环境里经常不允许引额外框架此时模拟 Bootstrap 下拉菜单的常见做法是把菜单项藏在一个ul里点击入口时用slideToggle展开点击菜单外部时自动收起。$(#menuToggle).on(click, function(e) { e.preventDefault(); // 阻止默认跳转 $(this).next(.dropdown-menu).slideToggle(200); }); $(document).on(click, function(e) { if (!$(e.target).closest(.has-dropdown).length) { $(.dropdown-menu).slideUp(200); // 点击菜单外部时收起 } });li classhas-dropdown a href# idmenuToggle更多/a ul classdropdown-menu styledisplay:none; lia href#私人 FM/a/li lia href#收藏/a/li lia href#上传歌曲/a/li /ul /lislideToggle(200)中的 200 是动画时长单位毫秒。在document上监听点击事件再通过closest(.has-dropdown)判断点击位置是否属于菜单内部这是 Bootstrap 下拉菜单的核心逻辑也是点外部关闭弹层这类交互最常用的实现方式。这个模式不依赖任何第三方库放在人工智能大作业的展示页里能让完成度明显提高。3.4 页面滚动与一键返回顶部长列表滚动后用户要回到顶部最顺手的方式是右下角悬浮按钮。这里给出一个常见的返回顶部实现代码可以直接挂在刚才的菜单逻辑后面var $backTop $(button classback-top styledisplay:none;返回顶部/button); $(body).append($backTop); $(window).on(scroll, function() { if ($(this).scrollTop() 300) { $backTop.fadeIn(); } else { $backTop.fadeOut(); } }); $backTop.on(click, function() { $(html, body).animate({ scrollTop: 0 }, 400); });scrollTop() 300是显示阈值超过 300px 显示按钮体验最自然动画时长 400 毫秒比默认的 200 毫秒更有平滑感。把按钮用 jQuery 直接创建并插入 body省去了在 HTML 里写死一个隐藏按钮的步骤。4. 数据驱动JSON 模拟、搜索过滤与播放队列联动只做前端展示的音乐站数据可以写死在 JavaScript 数组里但既然题目前缀带人工智能项目实践往往会要求体现出一点数据处理思想把歌曲当作数据源让界面跟随数据变化。用 JSON 模拟后端接口返回再用 jQuery 渲染到页面是这类课程设计最常见的技术路径。4.1 用 JSON 管理歌曲数据的好处把歌曲数据抽离出来之后HTML 里不再写死任何歌名。修改歌单只需要改 JSON 数据页面结构完全不动。这个思想是 MVC 里 M模型的简化版人工智能大作业里尤其合适模型返回的结果是数据前端只是把数据画出来两边解耦后调试起来非常方便。定义一个 JSON 数组模拟接口返回{ code: 200, msg: success, data: [ { id: 1, name: Neural Lullaby, singer: AI Ensemble, duration: 214, genre: 电子 }, { id: 2, name: Data Stream, singer: Algorithm, duration: 186, genre: 氛围 }, { id: 3, name: Pixel Dream, singer: Deep Synth, duration: 243, genre: 电子 } ] }外层用code/msg/data包一层课程答辩时更容易衔接后端同学给的真实接口格式。4.2 渲染列表与搜索过滤渲染函数用$.each遍历数据拼出 HTML 字符串后一次性插入列表容器var songList [ { id: 1, name: Neural Lullaby, singer: AI Ensemble, duration: 214 }, { id: 2, name: Data Stream, singer: Algorithm, duration: 186 }, { id: 3, name: Pixel Dream, singer: Deep Synth, duration: 243 } ]; function renderList(dataList) { var html ; $.each(dataList, function(i, item) { html li classsong-item>$(#searchInput).on(input, function() { var keyword $.trim($(this).val()).toLowerCase(); if (!keyword) { renderList(songList); return; } var filtered songList.filter(function(item) { return item.name.toLowerCase().indexOf(keyword) -1 || item.singer.toLowerCase().indexOf(keyword) -1; }); renderList(filtered); });.trim()去掉首尾空格.toLowerCase()让英文大小写不敏感这两个处理能避免用户输入带空格或大写字母时搜不到结果。indexOf(keyword) -1对中文天然适用不需要额外编码处理。4.3 播放队列与事件委托联动搜索和播放要联动点击搜索结果里的某一项播放器加载并播放同时高亮当前条目。高亮样式放在 CSS 里jQuery 只负责切换类名$(#songList).on(click, .song-item, function() { var id $(this).data(index); var track songList.find(function(item) { return item.id id; }); if (!track) return; $(#player).attr(src, audio/ track.name.toLowerCase().replace(/ /g, -) .mp3); $(#playerInfo).text(track.name - track.singer); $(#player)[0].play(); $(.song-item.active).removeClass(active); $(this).addClass(active); });这里的音频文件名做了两件事toLowerCase()统一小写replace(/ /g, -)把空格替换成连字符避免文件名带空格导致 URL 解析出错。常见的误区是列表用.html()重绘之后绑定在子元素上的事件全部失效。解决方式就是示例中的做法把事件委托到父级#songList上只要列表容器不销毁点击任何子元素都能通过事件冒泡触发回调。这是动态列表场景最稳的绑定模式。4.4 空结果与加载失败的兜底展示搜索不到内容界面不能直接剩下一个空列表。在搜索分支里加一个判断if (filtered.length 0) { $(#songList).html(li classempty-tip没有找到相关歌曲换个关键词试试/li); } else { renderList(filtered); }空结果提示本身也是一个列表项样式上居中对齐、字体用灰色用户不会误以为是列表行。真实的项目如果要从接口拉数据配套的逻辑是$.getJSON加上fail回调$.getJSON(api/song-list.json) .done(function(res) { if (res.code 200) { renderList(res.data); } }) .fail(function() { $(#songList).html(li classempty-tip加载失败请检查接口地址/li); });done和fail是 jQuery 3.x 推荐的写法取代了老教程里的success/error参数。就算课程项目里没有真正后端把数据包一层 JSON 模拟返回展示效果和代码结构都会更接近真实工作流。5. 收尾把静态页变成可用产品的 4 个验证细节页面能跑起来只是第一步交作业或演示前还应该用可复现的方法检查几个容易翻车的点。5.1 用开发者工具验证响应式与触控区域打开 Chrome 开发者工具的设备模拟DevTools Toggle device toolbar把宽度分别调到 375px、768px、1280px 三档检查三点导航是否换行错位、搜索框是否被挤压、播放条是否遮挡内容。播放条是position: fixed会悬浮在内容上方列表最后一条歌会被它盖住一部分。解决办法是在.site-content上补padding-bottom: 80px高度比播放条略大即可。5.2 最容易翻车的三个细节第一是浏览器自动播放策略。Chrome 不允许页面加载后直接调用play()必须在用户点击事件回调里触发。本文所有播放调用都发生在点击列表项或按钮的回调里所以是安全的但如果你把loadTrack(0)放在$(document).ready里想实现进页面自动放歌大概率会被浏览器拦截这是课程演示里最常见的翻车点。第二是音频格式兼容.mp3在 Chrome、Edge、Firefox 里都可用实验机器上尽量不选.wav或.ogg。第三是文件路径用相对路径audio/track1.mp3不要写C:/Users/xxx/audio/...否则换一台电脑就全部 404。最后整理一张自测清单按这个顺序过一遍基本不会有低级问题检查项预期结果排查方向audio的src可访问控制台 Network 无 404确认相对路径正确搜索中文关键词列表实时刷新input事件是否绑定在输入框上窗口宽度调到 375px无横向滚动条检查播放条和表格是否有固定min-width点击菜单外部下拉菜单收起closest(.has-dropdown)判断是否在菜单区域内首次点击歌曲能播放按钮进入播放状态play()是否在用户点击回调内触发5.3 目录组织与提交前检查最后把文件整理成标准布局比散落在一堆目录里更容易拿到高分music-site/ ├── index.html ├── css/ │ └── style.css ├── js/ │ ├── jquery-3.6.0.min.js │ └── main.js ├── audio/ │ ├── track1.mp3 │ ├── track2.mp3 │ └── track3.mp3 └── api/ └── song-list.jsonapi/目录模拟后端接口main.js里通过$.getJSON读取它演示时可以直接说明这里替换成真实接口即可。提交前把main.js里所有console.log注释掉把页面标题、版权年份改成自己的信息这套基于 HTML CSS jQuery 的音乐网站就能在课程演示环境里稳定跑通。本文还有配套的精品资源点击获取
网站建设高端定制企业官网