概览
我们将创建一个美观且功能齐全的音乐播放器,它将包含以下功能:
- 播放/暂停
- 上一曲/下一曲
- 进度条(可拖动)
- 当前播放时间/总时长
- 音量控制
- 播放列表
- 显示当前播放歌曲信息(封面、标题、艺术家)
我们将使用 jQuery 来处理 DOM 操作和事件,使用 CSS3 来美化界面,使用 HTML5 的 <audio> 元素 来处理音频。
第 1 步:准备工作 (HTML & CSS)
我们需要一个基本的 HTML 结构和一些 CSS 样式来构建播放器的界面。
1 HTML 结构 (index.html)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">jQuery 音乐播放器</title>
<link rel="stylesheet" href="style.css">
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<div class="music-player">
<!-- 歌曲信息显示区 -->
<div class="now-playing">
<img src="https://via.placeholder.com/150" alt="Album Cover" id="album-cover">
<div class="song-info">
<h2 id="song-title">歌曲标题</h2>
<p id="artist-name">艺术家</p>
</div>
</div>
<!-- 进度条区域 -->
<div class="progress-container">
<span id="current-time">0:00</span>
<div class="progress-bar">
<div class="progress"></div>
</div>
<span id="duration">0:00</span>
</div>
<!-- 控制按钮 -->
<div class="controls">
<button id="prev-btn" class="control-btn">
<i class="fas fa-step-backward"></i>
</button>
<button id="play-pause-btn" class="control-btn play-pause">
<i class="fas fa-play"></i>
</button>
<button id="next-btn" class="control-btn">
<i class="fas fa-step-forward"></i>
</button>
</div>
<!-- 音量控制 -->
<div class="volume-container">
<i class="fas fa-volume-up"></i>
<input type="range" id="volume-slider" min="0" max="1" step="0.01" value="1">
</div>
<!-- 播放列表 -->
<div class="playlist">
<h3>播放列表</h3>
<ul id="playlist-songs">
<!-- 播放列表项将通过 jQuery 动态生成 -->
</ul>
</div>
</div>
<!-- 隐藏的 audio 元素,用于实际播放 -->
<audio id="audio-player"></audio>
<!-- 引入 Font Awesome 图标库 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<!-- 引入我们的 JavaScript 文件 -->
<script src="script.js"></script>
</body>
</html>
2 CSS 样式 (style.css)
为了让播放器看起来更美观,我们需要添加一些样式。
body {
font-family: 'Arial', sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.music-player {
background-color: #fff;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
width: 400px;
padding: 25px;
text-align: center;
}
.now-playing {
display: flex;
align-items: center;
margin-bottom: 20px;
}
#album-cover {
width: 100px;
height: 100px;
border-radius: 10px;
margin-right: 20px;
}
.song-info {
text-align: left;
}
.song-info h2 {
margin: 0 0 5px 0;
font-size: 1.2em;
}
.song-info p {
margin: 0;
color: #666;
}
.progress-container {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.progress-bar {
flex-grow: 1;
height: 6px;
background-color: #e0e0e0;
border-radius: 3px;
cursor: pointer;
position: relative;
}
.progress {
height: 100%;
background-color: #4CAF50;
border-radius: 3px;
width: 0%;
}
.controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
margin-bottom: 20px;
}
.control-btn {
background: none;
border: none;
font-size: 1.5em;
color: #333;
cursor: pointer;
transition: color 0.2s;
}
.control-btn:hover {
color: #4CAF50;
}
.control-btn.play-pause {
font-size: 2em;
}
.volume-container {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
}
#volume-slider {
width: 100px;
}
.playlist {
text-align: left;
background-color: #f9f9f9;
border-radius: 10px;
padding: 15px;
}
.playlist h3 {
margin-top: 0;
margin-bottom: 15px;
text-align: center;
}
#playlist-songs {
list-style: none;
padding: 0;
margin: 0;
}
#playlist-songs li {
padding: 10px;
border-bottom: 1px solid #ddd;
cursor: pointer;
transition: background-color 0.2s;
}
#playlist-songs li:hover {
background-color: #e9e9e9;
}
#playlist-songs li.active {
background-color: #e0f2f1;
font-weight: bold;
}
第 2 步:核心 JavaScript 逻辑 (script.js)
这是实现所有功能的核心部分,我们将在这里使用 jQuery 来操作 DOM 和处理事件。
$(document).ready(function() {
// 1. 获取 DOM 元素
const audio = $('#audio-player')[0]; // jQuery 对象转换为原生 DOM 元素以使用原生 API
const playPauseBtn = $('#play-pause-btn');
const prevBtn = $('#prev-btn');
const nextBtn = $('#next-btn');
const progressBar = $('.progress');
const progressContainer = $('.progress-bar');
const currentTimeEl = $('#current-time');
const durationEl = $('#duration');
const volumeSlider = $('#volume-slider');
const albumCover = $('#album-cover');
const songTitle = $('#song-title');
const artistName = $('#artist-name');
const playlistSongs = $('#playlist-songs');
// 2. 播放列表数据
const playlist = [
{
title: "晴天",
artist: "周杰伦",
src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
cover: "https://via.placeholder.com/150?text=晴天"
},
{
title: "七里香",
artist: "周杰伦",
src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3",
cover: "https://via.placeholder.com/150?text=七里香"
},
{
title: "稻香",
artist: "周杰伦",
src: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3",
cover: "https://via.placeholder.com/150?text=稻香"
}
];
let currentSongIndex = 0;
// 3. 初始化播放列表
function initPlaylist() {
playlistSongs.empty();
playlist.forEach((song, index) => {
const li = $('<li>').text(`${song.title} - ${song.artist}`).data('index', index);
if (index === currentSongIndex) {
li.addClass('active');
}
playlistSongs.append(li);
});
}
// 4. 加载歌曲
function loadSong(index) {
const song = playlist[index];
audio.src = song.src;
songTitle.text(song.title);
artistName.text(song.artist);
albumCover.attr('src', song.cover);
// 更新播放列表高亮
playlistSongs.find('li').removeClass('active');
playlistSongs.find(`li[data-index="${index}"]`).addClass('active');
// 如果当前是播放状态,则自动播放新歌曲
if (!audio.paused) {
audio.play();
}
}
// 5. 播放/暂停功能
function togglePlayPause() {
if (audio.paused) {
audio.play();
playPauseBtn.html('<i class="fas fa-pause"></i>');
} else {
audio.pause();
playPauseBtn.html('<i class="fas fa-play"></i>');
}
}
// 6. 格式化时间 (秒转 MM:SS)
function formatTime(seconds) {
const minutes = Math.floor(seconds / 60);
const remainingSeconds = Math.floor(seconds % 60);
return `${minutes}:${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}`;
}
// 7. 更新进度条
function updateProgress() {
const { duration, currentTime } = audio;
if (!isNaN(duration)) {
const progressPercent = (currentTime / duration) * 100;
progressBar.css('width', `${progressPercent}%`);
currentTimeEl.text(formatTime(currentTime));
durationEl.text(formatTime(duration));
}
}
// 8. 设置进度
function setProgress(e) {
const width = progressContainer.width();
const clickX = e.offsetX;
const duration = audio.duration;
audio.currentTime = (clickX / width) * duration;
}
// 9. 上一曲
function prevSong() {
currentSongIndex--;
if (currentSongIndex < 0) {
currentSongIndex = playlist.length - 1;
}
loadSong(currentSongIndex);
}
// 10. 下一曲
function nextSong() {
currentSongIndex++;
if (currentSongIndex >= playlist.length) {
currentSongIndex = 0;
}
loadSong(currentSongIndex);
}
// 11. 事件监听器
playPauseBtn.on('click', togglePlayPause);
prevBtn.on('click', prevSong);
nextBtn.on('click', nextSong);
progressContainer.on('click', setProgress);
// 音量控制
volumeSlider.on('input', function() {
audio.volume = $(this).val();
});
// 播放列表点击事件
playlistSongs.on('click', 'li', function() {
currentSongIndex = $(this).data('index');
loadSong(currentSongIndex);
audio.play();
playPauseBtn.html('<i class="fas fa-pause"></i>');
});
// audio 元素的事件
audio.addEventListener('timeupdate', updateProgress);
audio.addEventListener('ended', nextSong); // 歌曲结束时自动播放下一曲
// 初始化
initPlaylist();
loadSong(currentSongIndex);
});
第 3 步:如何运行
- 创建文件:将上面的代码分别保存为
index.html、style.css和script.js三个文件,并放在同一个文件夹下。 - 放置音乐文件:将你的音乐文件(如
.mp3)放在项目文件夹中,并修改playlist数组中的src属性为你的音乐文件路径(src: "my_music/song1.mp3"),或者,你可以使用我提供的在线示例链接。 - 打开网页:用浏览器打开
index.html文件,你就可以看到一个功能完整的音乐播放器了!
代码解析与最佳实践
-
jQuery vs. 原生 JS:
- 我们混合使用了 jQuery 和原生 JavaScript,对于选择元素、绑定事件、修改 CSS 等操作,jQuery 非常简洁。
- HTML5 的
<audio>元素本身提供了一套原生 API(如audio.play(),audio.pause(),audio.currentTime),在需要直接操作这些 API 时,将 jQuery 对象(如$('#audio-player'))转换为原生 DOM 元素($('#audio-player')[0])是更直接高效的方式。
-
事件委托:
- 在
playlistSongs.on('click', 'li', ...)这一行,我们使用了事件委托,这是处理动态生成元素的最佳实践,即使<li>是后来通过 jQuery 动态添加的,这个事件监听器依然能正确工作。
- 在
-
关注点分离:
- HTML 负责结构。
- CSS 负责样式。
- JavaScript (jQuery) 负责行为和逻辑。
- 这种分离让代码更易于维护和理解。
-
可扩展性:
- 播放列表数据被存储在一个 JavaScript 数组中,如果你想从服务器加载歌曲列表,你只需要用 AJAX (jQuery 的
$.ajax或$.get) 请求一个 JSON 数据,然后用返回的数据替换掉本地的playlist数组即可,其他逻辑几乎不需要改动。
- 播放列表数据被存储在一个 JavaScript 数组中,如果你想从服务器加载歌曲列表,你只需要用 AJAX (jQuery 的
这个例子为你提供了一个坚实的基础,你可以基于它继续添加更多高级功能,比如随机播放、循环模式、歌词显示等,祝你编码愉快!
