纯HTML+CSS+JS制作音乐播放器(附源码)

由于课程要求,不使用任何框架(诸如jquery之类的)来实现一个音乐播放器,我查找了半天没能找到自己心仪的,索性便自己写了。写好之后发出来分享一下。

效果截图

话不多说,首先放图。

 

 

 播放列表做的属实难看了点,但是我想不到什么优化的好点子,又嫌麻烦不想给他加上编曲人之类的信息,索性就这样放着了。如果有什么优化的点子可以私信一起探讨一下。

页面布局灵感来自于qq音乐。

实现功能

  1. 进度条功能

  2. 时间功能

  3. 播放/暂停功能

  4. 上一首/下一首

  5. 切换播放模式功能

  6. 音量调节功能

  7. 播放MV功能

  8. 倍速功能

  9. 音乐列表功能

实现逻辑

  • 进度条功能。

进度条会随着音乐的播放逐渐向后移动,这是通过audio的timeupdate事件来实现的,每时每刻都会重新计算进度条长度。

// 更新进度条
audio.addEventListener('timeupdate', updateProgress); // 监听音频播放时间并更新进度条
function updateProgress() {
    var value = audio.currentTime / audio.duration;
    progress.style.width = value * 100 + '%';
    playedTime.innerText = transTime(audio.currentTime);
}

点击进度条可以跳转至指定地方播放,这是通过所有DOM元素都有的事件mousedown来实现的。

// 点击进度条跳到指定点播放
progressTotal.addEventListener('mousedown', function (event) {
    // 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
    if (!audio.paused || audio.currentTime != 0) {
        var pgsWidth = parseFloat(window.getComputedStyle(progressTotal, null).width.replace('px', ''));
        var rate = event.offsetX / pgsWidth;
        audio.currentTime = audio.duration * rate;
        updateProgress(audio);
    }
});
  • 时间功能

更新进度条的同时左下角时间会更新,这是通过这一行代码来实现的:

playedTime.innerText = transTime(audio.currentTime);
  • 播放/暂停功能

这个功能实现起来很简单,检测当前音频播放状态并作出相应反应即可。

// 暂停/播放功能实现
pause.onclick = function (e) {
    if (audio.paused) {
        audio.play();
        rotateRecord();
        pause.classList.remove('icon-play');
        pause.classList.add('icon-pause');
    } else {
        audio.pause();
        rotateRecordStop();
        pause.classList.remove('icon-pause');
        pause.classList.add('icon-play');
    }
}
  • 上一首/下一首

对相应按钮添加点击事件,点击上一首按钮时改变当前播放音乐的序号,并且重新载入该音乐。下一首功能也是如此实现。

// 上一首
skipForward.addEventListener('click', function (event) {
    musicId = musicId - 1;
    if (musicId < 0) {
        musicId = 3;
    }
    initAndPlay();
});

// 下一首
skipBackward.addEventListener('click', function (event) {
    musicId = musicId + 1;
    if (musicId > 3) {
        musicId = 0;
    }
    initAndPlay();
});
  • 切换播放模式功能

有三种内置的播放模式:单曲循环,随机播放,列表循环。每次点击播放模式按钮后切换至下一种播放模式。

// 播放模式设置
var modeId = 1;
mode.addEventListener('click', function (event) {
    modeId = modeId + 1;
    if (modeId > 3) {
        modeId = 1;
    }
    mode.style.backgroundImage = "url('img/mode" + modeId.toString() + ".png')";
});

audio.onended = function () {
    if (modeId == 2) {
        // 跳转至下一首歌
        musicId = (musicId + 1) % 4;
    }
    else if (modeId == 3) {
        // 随机生成下一首歌的序号
        var oldId = musicId;
        while (true) {
            musicId = Math.floor(Math.random() * 3) + 0;
            if (musicId != oldId) { break; }
        }
    }
    initAndPlay();
}
  • 音量调节功能

实时获取滑块当前的长度并且更新音频音量,用到的还是audio的timeupdate函数。同时点击音量调节按钮之后可以设置静音,使用click事件即可实现。

// 滑块调节音量
audio.addEventListener('timeupdate', updateVolumn);
function updateVolumn() {
    audio.volume = volumeTogger.value / 70;
}

// 点击音量调节设置静音
volume.addEventListener('click', setNoVolumn);
function setNoVolumn() {
    if (volumeTogger.value == 0) {
        if (lastVolumn == 0) {
            lastVolumn = 70;
        }
        volumeTogger.value = lastVolumn;
        volume.style.backgroundImage = "url('img/音量.png')";
    }
    else {
        lastVolumn = volumeTogger.value;
        volumeTogger.value = 0;
        volume.style.backgroundImage = "url('img/静音.png')";
    }
}
  • 播放MV功能

此处我考虑了要将MV放置在新窗口还是旧的窗口,最终还是决定新开一个窗口来播放MV。那么这就涉及到窗口之间的传值。使用window.sessionStorage来实现。

// MV功能
MV.addEventListener('click', function (event) {
    // 向新窗口传值
    var storage_list = window.sessionStorage;
    storage_list['musicId'] = musicId;
    window.open("video.html");
});

此处放上新窗口的body部分代码:

<body>
    <video controls width="250">
        <source id="source" src="mp4/video0.mp4" type="video/mp4">
    </video>
    </video>
    <script>
        //获取前面的存储的musicId值
        var storage = window.sessionStorage;
        var cur_str = storage.musicId;
        document.getElementById('source').src = "mp4/video" + cur_str.toString() + ".mp4";
    </script>
</body>

由于该部分代码量很小,并且不是项目主体部分,因此css和javascript均使用内嵌式来实现。

最终效果:点击不同音乐的MV按钮,可以打开相应的MV视频界面。

  • 倍速功能

一共内置了四种倍速:1.0X,1.5X,2.0X,0.5X。每次点击按钮后会切换到下一种倍速,并改变其UI。由于此处的倍速种类较少,直接使用if else来实现这一功能。如果倍速种类较多,则需要使用int 变量与string变量之间的相互转化来实现。

// 倍速功能(这里直接暴力解决了)
speed.addEventListener('click', function (event) {
    var speedText = speed.innerText;
    if (speedText == "1.0X") {
        speed.innerText = "1.5X";
        audio.playbackRate = 1.5;
    }
    else if (speedText == "1.5X") {
        speed.innerText = "2.0X";
        audio.playbackRate = 2.0;
    }
    else if (speedText == "2.0X") {
        speed.innerText = "0.5X";
        audio.playbackRate = 0.5;
    }
    else if (speedText == "0.5X") {
        speed.innerText = "1.0X";
        audio.playbackRate = 1.0;
    }
});
  • 音乐列表功能

首先需要在界面右方固定音乐列表面板:

<div class="music-list" id="music-list">
        <div class="music-list-container">
            <div class="music-list-title">播放队列</div>
            <hr class="line">
            <div class="all-list">
                <div id="music0">洛春赋</div>
                <div id="music1">Yesterday</div>
                <div id="music2">江南烟雨色</div>
                <div id="music3">Vision pt.II</div>
            </div>
        </div>
    </div>

实现的效果如下图:

效果实在不算好看,但我也没想到什么能够让他变得美观的优化方法。

对其加上css滑动动画:

@keyframes hideAni {
    from {
        transform: translateX(0%);
    }

    to {
        transform: translateX(100%);
    }
}

@keyframes showAni {
    from {
        transform: translateX(100%);
    }

    to {
        transform: translateX(0%);
    }
}

最后在js中加入打开面板和关闭面板的逻辑,实现起来很简单,使用click事件即可。

// 点击列表展开音乐列表
list.addEventListener('click', function (event) {
    musicList.classList.remove("list-card-hide");
    musicList.classList.add("list-card-show");
    musicList.style.display = "flex";
    closeList.style.display = "flex";
    closeList.addEventListener('click', closeListBoard);
});

// 点击关闭面板关闭音乐列表
function closeListBoard() {
    musicList.classList.remove("list-card-show");
    musicList.classList.add("list-card-hide");
    closeList.style.display = "none";
}

打开列表面板时,左侧实际上覆盖了一个透明的面板,由此来实现点击空白部分关闭面板的功能。需要注意的是关闭面板后需要将该透明面板的display设置为none,否则会遮蔽下层按钮的点击事件。

 写在最后

代码中使用到的包括图片、视频、音频等所有素材仅为展示使用,相互之间没有任何关联,如有需要可自行更改。

github地址:GitHub - falysha/musicPlayer: 原生HTML+CSS+JS,未使用任何框架

 

  • 22
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
下面是一个简单的百分比计算器的HTMLCSS和JavaScript源代码示例: HTML部分: ```html <!DOCTYPE html> <html> <head> <title>百分比计算器</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div class="calculator"> <input type="text" id="display" readonly> <div class="buttons"> <button onclick="addToDisplay('7')">7</button> <button onclick="addToDisplay('8')">8</button> <button onclick="addToDisplay('9')">9</button> <button onclick="addToDisplay('/')">÷</button> <button onclick="addToDisplay('4')">4</button> <button onclick="addToDisplay('5')">5</button> <button onclick="addToDisplay('6')">6</button> <button onclick="addToDisplay('*')">×</button> <button onclick="addToDisplay('1')">1</button> <button onclick="addToDisplay('2')">2</button> <button onclick="addToDisplay('3')">3</button> <button onclick="addToDisplay('-')">-</button> <button onclick="addToDisplay('0')">0</button> <button onclick="addToDisplay('.')">.</button> <button onclick="calculate()">=</button> <button onclick="addToDisplay('%')">%</button> </div> </div> <script src="script.js"></script> </body> </html> ``` CSS部分(style.css): ```css .calculator { width: 200px; margin: 0 auto; } #display { width: 100%; height: 30px; margin-bottom: 10px; } .buttons button { width: 50px; height: 50px; } ``` JavaScript部分(script.js): ```javascript function addToDisplay(value) { document.getElementById('display').value += value; } function calculate() { let expression = document.getElementById('display').value; let result = eval(expression); // 如果结果以数字结尾,将它转换为百分比 if (!isNaN(result)) { result = result * 100 + '%'; } document.getElementById('display').value = result; } ``` 这个计算器有一个文本框用于显示输入和结果。数字、运算符(除法、乘法、减法)、小数点和百分号按钮被添加到按钮组中,并通过调用JavaScript函数将它们添加到显示文本框中。等号按钮用于计算表达式,并将结果显示在文本框中。如果结果以数字结尾,它将被转换为百分比形式。 请注意,这仅是一个简单的示例,并且没有进行输入验证和错误处理。在实际中,你可能需要添加更多的功能和验证以确保计算器的正确性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值