基于原生JavaScript实现网页音乐播放器

作者:闭包旅人

时间:2026-10-24

浏览:197

本文详细讲解如何使用原生JavaScript、HTML5和CSS构建一个网页音乐播放器。内容涵盖播放器界面布局、歌曲列表动态加载、播放控制逻辑及进度条实现,通过具体代码示例展示如何操作Audio对象及相关事件。

文章目录

网页音乐播放器概述

本文将介绍如何利用JavaScript技术在网页中开发一个音乐播放器。

音乐播放器是网页应用中常见的功能,接下来我们将探讨其具体的实现方法。

下图展示了本文所构建的播放器界面效果。

网页音乐播放器概述 

播放器界面结构分析

从整体结构来看,播放器自上而下分为三个部分:顶部的标题栏(head),显示“我的音乐”;中间的内容区域(body),用于展示歌曲列表;底部的控制栏(foot),包含播放控制按钮、当前曲目名称、播放进度条及总时长显示。标题栏仅包含文字标题,内容区展示歌单,每首歌曲配有播放图标(仅在播放时显示)及歌曲信息,底部则集成了播放控制图标、当前播放歌曲名、进度条和时长信息。

HTML与CSS布局实现

在布局方面,我们遵循结构与样式分离的原则,使用HTML构建页面结构,使用CSS定义样式。

网页结构布局方面,歌曲列表并非硬编码,而是通过加载JSON对象动态生成。因此,HTML中仅保留歌曲列表的格式模板。对于“上一首”、“播放/暂停”和“下一首”图标,使用a标签实现,并将图标作为背景图片嵌入。播放进度条由两个div组成:内部div显示灰色代表总进度,外部div显示白色代表当前播放进度。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="./css/yinyue.css" >
</head>
<body>
<!--整个播放器部分-->
<div class="music-list">
    <!--标题部分-->
    <div class="head">我的音乐</div>
    <!--内容部分-->
    <div class="body" id="tbody">
        <!--每一首歌曲的格式-->
        <div class="item">
            <!--歌曲播放时的小图标-->
            <div class="item-logo box11"><img src="imgs/playing.gif"></div>
            <!--歌曲信息-->
            <div class="item-name">手掌心——丁当</div>
        </div>
    </div>
    <!--底部部分-->
    <div class="foot">
        <!--上一首/播放、暂停/下一首的图标-->
        <div class="box1">
            <!--上一首的图标-->
            <a href="javascript:;" class="btn-pre"></a>
            <!--播放、暂停的图标-->
            <a href="javascript:;" class="btn-play" id="btnPlay"></a>
            <!--下一首的图标-->
            <a href="javascript:;" class="btn-next"></a>
        </div>
        <!--歌曲播放的当前时间-->
        <div class="box2 play-current">0.00</div>
        <!--歌曲播放的进度和歌曲名-->
        <div class="box3 mid">
            <!--歌曲名-->
            <span id="playingNmae" class="m-name">我的音乐</span>
            <!--歌曲播放的进度-->
            <div class="box31"></div>
            <div class="box32"><a href="" class=" rel="external nofollow" dot"></a></div>
        </div>
        <!--歌曲播放的总时间-->
        <div class="box4 play-duration">4.13</div>
    </div>
</div>
<script src="js/data.js"></script>
<script src="js/index.js"></script>
</body>
</html>

网页样式布局方面,用户可根据需求自定义字体和颜色。在设置背景图片时,如使用background: url("../imgs/play-default.png") no-repeat;,需注意url中的路径包含两个点(..)以表示退出当前目录至根目录,同时必须设置no-repeat属性以防止图片平铺。使用绝对定位时,需遵循“子绝父相”原则,并合理设置z-index属性。


/*去除标签中自带的内外边距*/
* {
    margin: 0;
    padding: 0;
}
/*设置整个播放器样式:
布局是弹性盒,
水平居中,
宽度和高度,
带边框,
设置弹性盒子的弹性方向:column(垂直的竖向)
*/
.music-list {
    display: flex;
    margin: 0 auto;
    height: 600px;
    width: 400px;
    border: 1px solid #ccc;
    flex-direction: column;
}
/*设置标题部分*/
.head{
    flex: 1;
    background: #3498db;
    color: #fff;
    font: 24px "华文行楷";
    display: flex;
    /*横轴居中*/
    justify-content: center;
    /*纵轴居中*/
    align-items: center;
    border-bottom: 1px solid white;
    box-sizing: border-box;
}
/*设置内容部分*/
.body {
    flex: 7;
    /*超出部分隐藏*/
    overflow-x: hidden;
}
/*设置底部部分*/
.foot {
    flex: 2;
    display: flex;
    background: #3498db;
    color: #fff;
    font-size: 14px;
    border-top: 1px solid white;
    box-sizing: border-box;
}
/*设置每一首歌曲的格式*/
.item {
    display: flex;
    height: 50px;
    line-height: 50px;
    background: #3498db;
    color: #fff;
    font-size: 14px;
    cursor: pointer;
    transition: all .5s;
}
/*除了最后一首歌曲其他歌曲都显示下边框*/
.item:not(:last-child) {
    border-bottom: 1px solid white;
}
/*设置歌曲播放时的小图标的背景颜色*/
.box11 {
    background: #f0f0f0;
}
/*设置歌曲信息*/
.item-name {
    flex: 6;
    /*不挨着边框写*/
    padding: 0 10px;
}
/*鼠标悬停的效果*/
.item:hover {
    background: #2980b9;
}
/*鼠标点击的效果*/
.item:active {
    /*点击事件想要立体效果可以加盒子阴影,相对定位*/
    position: relative;
    top: 2px;
    left: 2px;
    box-shadow: 5px 5px 10px rgba(0, 0, 0, .5);
}
/*设置上一首/播放、暂停/下一首的图标的占据大小*/
.box1 {
    flex: 3;
    display: inline-block;
}
/*设置歌曲播放的当前时间的占据大小*/
.box2 {
    flex: 1;
    display: inline-block;
    padding: 50px 0;
    text-align: left;
}
/*设置歌曲播放的进度和歌曲名的占据大小*/
.box3 {
    flex: 5;
    display: inline-block;
    position: relative;
    padding: 35px 0;
}
/*设置歌曲播放的总时间的占据大小*/
.box4 {
    flex: 1;
    display: inline-block;
    padding: 50px 0;
    text-align: right;
}
/*分配上一首/播放、暂停/下一首的图标大小*/
.box1 a {
    display: inline-block;
    margin: 50px 0;
    width: 30%;
    height: 50%;
}
/*设置上一首的图标*/
.btn-pre {
    background: url("../imgs/pre-default.png") no-repeat;
    cursor: pointer;
}
/*设置上一首的图标鼠标悬停效果*/
.btn-pre:hover {
    background: url("../imgs/pre-active.png") no-repeat;
}
/*设置播放的图标*/
.btn-play {
    background: url("../imgs/play-default.png") no-repeat;
    cursor: pointer;
}
/*设置播放的图标鼠标悬停效果*/
.btn-play:hover {
    background: url("../imgs/play-active.png") no-repeat;
}
/*设置暂停的图标*/
.btn-pause {
    background: url("../imgs/pause-default.png") no-repeat;
    cursor: pointer;
}
/*设置暂停的图标鼠标悬停效果*/
.btn-pause:hover {
    background: url("../imgs/pause-active.png") no-repeat;
}
/*设置下一首的图标*/
.btn-next {
    background: url("../imgs/next-default.png") no-repeat;
    cursor: pointer;
}
/*设置下一首的图标鼠标悬停效果*/
.btn-next:hover {
    background: url("../imgs/next-active.png") no-repeat;
}
/*设置歌曲名的字体*/
.m-name {
    font: 20px "楷体";
}
/*设置歌曲播放总进度*/
.box31 {
    position: absolute;
    width: 100%;
    height: 2px;
    background: #cacaca;
    z-index: 1;
}
/*设置歌曲播放当前进度*/
.box32 {
    position: absolute;
    width: 20%;
    height: 2px;
    background: white;
    z-index: 2;
}
/*跟着歌曲播放当前进度一起动的小圆点*/
.dot {
    position: absolute;
    display: inline-block;
    right: 0;
    top: -2px;
    height: 5px;
    width: 5px;
    border-radius: 2.5px;
    background: #fff;
}

JavaScript核心逻辑

JavaScript代码部分:由于播放图标和暂停图标需要交替显示,且作为背景图片,可以通过切换a标签的class来更换背景。在实现播放进度控制时,可监听audio对象的loadeddata、timeupdate和ended事件;利用ended事件可实现自动播放下一首歌曲的功能。在实现快进和快退功能时,需获取鼠标点击位置(即距离起始点的距离),通过修改player.currentTime的值来改变歌曲播放进度。


// 创建一个播放器dom对象
var player = document.createElement('audio');
//设置一个值保存当前播放歌曲的索引
var currentIndex = 0;
//设置一个标记判断歌曲是否播放
var isPlay = false;
​
//动态加载歌曲
(function () {
    //设置一个值保存所有歌曲dom对象
    var html = '';
    //获取所有歌曲的dom对象
    for (var i = 0; i < musics.length; i++) {
        var m = musics[i];
        //设置每一首歌曲的格式
        html += `<div class="item" data-index="${i}">
                      <div class="item-logo box11"></div>
                      <div class="item-name">${m.name}---${m.artist}</div>
                 </div>`
    }
    //添加所有歌曲
    document.getElementById('tbody').innerHTML = html;
    //给播放器一个默认的播放地址
    player.src = musics[currentIndex].path;
})();
​
//为每一首歌曲设置点击事件
var trs = document.querySelectorAll('.item')
for (let i = 0; i < trs.length; i++) {
    trs[i].addEventListener('click', function () {
        //清除上一首歌曲的播放状态
        clearStatus();
        //获取歌曲索引
        var index = this.dataset.index;
        currentIndex = index;
        var msc = musics[index];
        //给播放器设置的播放地址
        player.src = msc.path;
        //开始播放
        startPlayer();
    })
}
//函数:开始播放
function startPlayer() {
    //设置播放标记
    isPlay = true;
    // 播放歌曲
    player.play();
    trs[currentIndex].style.background = '#2980b9';
    // 添加播放歌曲的小图标
    trs[currentIndex].querySelector('.item-logo').innerHTML = '<img src="imgs/playing.gif">';
    //设置图标为播放状态
    document.querySelector('#btnPlay').className = 'btn-pause';
    //设置歌曲名
    document.querySelector('#playingNmae').innerText = `${musics[currentIndex].name} - ${musics[currentIndex].artist}`;
}
//函数:清除上一首歌曲的播放状态
function clearStatus() {
    trs[currentIndex].style.background = '';
    trs[currentIndex].querySelector('.item-logo').innerHTML = '';
}
//函数:暂停播放
function pausePlay() {
    //暂停播放
    player.pause();
    //设置播放标记
    isPlay = false;
    //设置图标为暂停状态
    document.getElementById('btnPlay').className = 'btn-play';
}
//函数:实现上一首歌曲功能的点击事件
document.querySelector('.btn-pre').addEventListener('click', function () {
    //暂停播放
    pausePlay();
    //清除上一首歌曲的播放状态
    clearStatus();
    //实现上一首歌曲功能
    if (currentIndex == 0) {
        currentIndex = musics.length - 1;
    } else {
        --currentIndex;
    }
    console.log(currentIndex)
    //给播放器设置的播放地址
    player.src = musics[currentIndex].path;
    startPlayer();
​
})
//函数:实现播放歌曲功能的点击事件
document.getElementById('btnPlay').addEventListener('click', function () {
    //通过判断播放标志
    if (isPlay) {
        pausePlay();
    } else {
        startPlayer();
    }
})
//函数:实现下一首歌曲功能的点击事件
document.querySelector('.btn-next').addEventListener('click', function () {
    pausePlay();
    clearStatus();
    if (currentIndex == musics.length - 1) {
        currentIndex = 0;
    } else {
        ++currentIndex;
    }
    console.log(currentIndex)
    player.src = musics[currentIndex].path;
    startPlayer();
​
})
//设置歌曲播放进度
var now = 0;
var total = 0;
//歌曲数据加载完后的事件
player.addEventListener('loadeddata', function () {
    // 歌曲当前的进度(时间)
    now = player.currentTime;
    // 歌曲总的进度(时间)
    total = player.duration;
    //把歌曲进度(时间)显示到播放器上
    document.querySelector('.play-current').innerText = fmtTime(now);
    document.querySelector('.play-duration').innerText = fmtTime(total);
})
//当currentTime(歌曲当前进度时间)更新时会触发timeupdate事件
player.addEventListener('timeupdate', function () {
    //获取歌曲当前的进度(时间)
    now = player.currentTime;
    // 歌曲当前的进度
    var p = now / total * 100 + '%';
    //把歌曲当前的进度同步到进度条上
    document.querySelector('.box32').style.width = p;
    document.querySelector('.play-current').innerText = fmtTime(now);
})
//歌曲结束事件(自动播放下一首歌曲的功能)
player.addEventListener('ended', function () {
    //清除上一首歌曲的播放状态
    clearStatus();
    //播放下一首歌曲
    currentIndex++;
    if (currentIndex >= musics.length) {
        currentIndex = 0;
    }
    player.src = musics[currentIndex].path;
    startPlayer();
})
//前进歌曲事件
document.querySelector('.box31').addEventListener('click', function (e) {
    //获取鼠标点击的位置
    let right = e.offsetX;
    // 设置进度条到鼠标点击的位置
    document.querySelector('.box32').style.width = right;
    //计算鼠标点击的位置歌曲的进度
    let seekTo = right/200*total;
    //设置歌曲的进度
    player.currentTime=seekTo;
        })
//后退歌曲事件
document.querySelector('.box32').addEventListener('click', function (e) {
    let left = e.offsetX;
    document.querySelector('.box32').style.width = left;
    let seekTo = left/200*total;
    player.currentTime=seekTo;
})
//函数:格式化时间
function fmtTime(time) {
    time *= 1000;
    time = new Date(time);
    var m = time.getMinutes();
    var s = time.getSeconds();
    m = m < 10 ? '0' + m : m;
    s = s < 10 ? '0' + s : s;
    return m + ':' + s;
}

歌曲数据musics:


var musics = [
    {
        artist: "GALA ",
        id: 1,
        name: "追梦赤子心",
        path: "musics/1.mp3"
    },
    {
        artist: "筷子兄弟",
        id: 2,
        name: "父亲",
        path: "musics/2.mp3"
    },
    {
        artist: "丁当",
        id: 3,
        name: "手掌心",
        path: "musics/3.mp3"
    },
    {
        artist: "佐々木李子",
        id: 4,
        name: "Good Night",
        path: "musics/4.mp3"
    },
    {
        artist: "张韶涵",
        id: 5,
        name: "隐形的翅膀",
        path: "musics/5.mp3",
    },
    {
        artist: "杨丞琳",
        id: 6,
        name: "雨爱",
        path: "musics/6.mp3",
    },
    {
        artist: "耀乐团",
        id: 7,
        name: "流星",
        path: "musics/7.mp3",
    },
    {
        artist: "逃跑计划",
        id: 8,
        name: "再飞行 (MV版)",
        path: "musics/8.mp3",
    },
    {
        artist: "金贵晟",
        id: 9,
        name: "虹之间",
        path: "musics/9.mp3",
    }
]

网页音乐播放器概述

总结与扩展

在学习jQuery及各类前端框架后,上述功能可借助这些工具实现,从而简化开发过程。

以上就是本文的全部内容,希望对各位的学习有所帮助,也欢迎大家继续支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章