原生H5+JS+CSS实现音乐播放器(上下一首,随机单曲循环播放,进度条,播放列表)

学了前端小半个月了,今天自己动手写一个音乐播放器实现的功能有 播放列表 ,随机单曲循环播放,上下一首,暂停和开始,静音,音量增加减少,进度条(收藏功能暂未实现,为了排版好看添加的,后续补充收藏等功能)。

话不多说,下面进入到h5页面的代码

 h5页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" type="text/css" href="./css/audioCSS.css">
</head>

<body id="body" background="./img/bandaotiehe.jpg">

<!--音乐播放图片-->
<img id="musicImg" src="" title="" width="400px" height="400px">

<!--音乐播放名字-->
<div id="musicName" class="name" id="musicName"></div>

<div class="item">
    <ul id="listALL">
    </ul>
</div>

<div class="main" id="main" >

    <audio id="audio" src=""></audio>
    <div id="collect" title="收藏"></div>
    <div id="list" title="列表"></div>
    <div id="selection" title="循环播放"></div>
    <div id="prev" title="上一首"></div>
    <div id="play" title="播放"></div>
    <div id="next" title="下一首"></div>
    <div id="slince" title="静音"></div>
    <div id="rise" title="加音量"></div>
    <div id="minus" title="减音量"></div>

</div>
<br>

<div class="progress" id="progress">
    <span class="cTime time" id="cTime">00:00</span> <!-- 当前时间 -->
    <meter value="0" max="100" id="meter" ></meter><!-- 进度条 -->
    <span class="tTime time" id="tTime">00:00</span> <!-- 总的时间 -->
</div>

<script src="./js/audio01.js"></script>
</body>
</html>

 下面CSS的页面

2023.3.25更新 #listALL   .firstMusic 样式 

{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

html,body{
    height: 100%;
    background-size:cover;
    backdrop-filter: blur(100px);
}

@keyframes totate {
    0% {
        transform: rotateZ(0);
    }

    50% {
        transform: rotateZ(180deg);
    }
    100% {
        transform: rotateZ(360deg);
    }
}
.main {
    justify-content: space-between;
    display: flex;
    overflow: hidden;

}

#musicImg {
    margin: 20px 650px;
    animation: totate 30s linear infinite;
    border-radius: 50%;
    background-image: url("../img/bandaotiehe.jpg");
    margin-bottom: 100px;
    animation-play-state: paused;

}
/*#musicImg:hover {
    animation-play-state: paused;
}*/

.item{

}


.firstMusic{

    color: red;
}


#listALL{
    position: absolute;
    width: 350px;
    display:none;
    background-color: #363636;
    top: 200px;
    opacity: 0.6;
}

.li{
    color: whitesmoke;
    height: 35px;
    font-size: 25px;
}


div {
    cursor: pointer;
    /* float: left; */
    margin: 10px auto;
    text-align: center;

}

#musicName{
    font-size: 40px;
    margin-bottom: 80px;
}


#collect{
    background: url("../img/icon_collect.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}

#selection{
    background: url("../img/xunhuanbofang.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}

#list{
    background: url("../img/24gl-playlistMusic.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}

#play{
    background: url(../img/bofang.png);
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}

#prev{
    background: url("../img/shangyishoushangyige.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}

#next{
    background: url("../img/xiayigexiayishou.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}

#slince{
    background: url("../img/24gl-volumeMiddle.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}

#rise{
    background: url("../img/24gl-volumeHigh.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}
#minus{
    background: url("../img/24gl-volumeLow.png");
    width: 40px;
    height: 40px;
    background-size: 100% 100%;
}


#cTime {
    /*float: left;*/
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    font-size: 18px;

    width: 20px;
}

#tTime {
    /*float: right;*/
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    font-size: 18px;
    width:300px;
}

#progress {
    margin-left: 10px;
    margin-right: 10px;
    /*background-color: cyan;*/
}


#meter {
    width: 720px;
    height: 18px;
    /*background: azure;
    margin-bottom: ;*/

}

JS的DOM创建

var audioDOM = document.getElementById("audio");
var collectDOM = document.getElementById("collect");
var selectionDOM = document.getElementById("selection");
var prevDOM = document.getElementById("prev");
var playDOM = document.getElementById("play");
var nextDOM = document.getElementById("next");
var slinceDOM = document.getElementById("slince");
var listDOM = document.getElementById("list");
var listALLDOM = document.getElementById("listALL");
var musicNameDOM = document.getElementById("musicName")
var musicImgDOM = document.getElementById("musicImg")
var tTimeDOM = document.getElementById("tTime")
var cTimeDOM = document.getElementById("cTime")
var meterDOM = document.getElementById("meter")
var bodyDOM = document.getElementById("body")
var riseDOM = document.getElementById("rise")
var minusDOM = document.getElementById("minus")

音乐列表

var songs = [

    {
        name: "周杰伦 - 半岛铁盒",
        photo: "../img/bandaotiehe.jpg"
    },
    {
        name: "周杰伦 - 外婆",
        photo: "../img/waipo.jpg"
    },
    {
        name: "周杰伦 - 完美主义",
        photo: "../img/wanmeizhuyi.jpg"
    },
    {
        name: "周杰伦 - 威廉古堡",
        photo: "../img/weiliangubao.jpg"
    },
    {
        name: "周杰伦 - 蜗牛",
        photo: "../img/woniu.jpg"
    },
    {
        name: "wake",
        photo: "../img/wake.jpg"
    },
    {
        name: "ceshi",
        photo: "../img/ceshi.png"
    }
]
musicNameDOM.innerText = songs[0].name
musicImgDOM.src = songs[0].photo

切换歌曲(上一首下一首)

首先创建两个变量记录当前歌曲的索引和歌曲的数量,给nextDOM创建事件监听,当点击触发 next(),因为我写了一个随机播放的功能,所以要考虑如果当前是随机播放的模式,,点击下一首也要随机播放,所以要给userChangeSong传一个随机数,用Math方法。

2023.3.25更新 添加每一次手动切换歌曲时重置进度条已加载的长度。

2023.3.28更新 将next方法里的给changeSong传值改为1.1 因为这样的话在点击列表播放里的索引位置为1的歌曲就不会冲突。

Math.floor(Math.random() * songs.length)
var currentSongIndex = 0;
var songsListLength = songs.length;
audioDOM.src = './mp3/' + songs[currentSongIndex].name + '.mp3'

nextDOM.addEventListener('click', next)

function next() {
    meterDOM.setAttribute('value',0)
    if (selectionDOM.title == "随机播放") {
        changeSong(Math.floor(Math.random() * songs.length))
    
    } else {
        changeSong(1.1)
    }
}

prevDOM.addEventListener('click', prev)

function prev() {
    meterDOM.setAttribute('value',0)
    if (selectionDOM.title == "随机播放") {
        changeSong(Math.floor(Math.random() * songs.length))
    
    } else {
        changeSong(-1.1)
    }
}

方法userChangeSong的代码 2023.3.28废除 因为跟changeSong方法重复

function userChangeSong(userNum) {
    currentSongIndex = userNum;
    audioDOM.src = './mp3/' + songs[currentSongIndex].name + '.mp3';
    audioDOM.play()

    for (let j = 0; j < selectDOM.children.length; j++) {
        selectDOM.children[j].classList.remove('firstMusic');
    }

    selectDOM.children[currentSongIndex].classList.add('firstMusic');

    playDOM.style.backgroundImage = 'url("./img/zanting.png")';
    musicNameDOM.innerText = songs[currentSongIndex].name;
    musicImgDOM.src = songs[currentSongIndex].photo;
    bodyDOM.background = ".img/" + songs[currentSongIndex].photo;
    musicImgDOM.style.animationPlayState = "running"

}

changeSong的方法 

2023.3.28 更新现在全局使用changSong方法 上面的userChangeSong废弃。

将从next和prev得到1.1和-1.1转换为整数类型,以防出错。

function changeSong(num) {

    if (num == 1.1 || num == -1.1){
        num = parseInt(num);
        currentSongIndex = (currentSongIndex + num + songsListLength) % songsListLength;
    }else {
        currentSongIndex = num;
    }

    audioDOM.src = './mp3/' + songs[currentSongIndex].name + '.mp3';

    for (let j = 0; j < selectDOM.children.length; j++) {
        selectDOM.children[j].classList.remove('nowMusic');
    }

    selectDOM.children[currentSongIndex].classList.add('nowMusic');

    audioDOM.play()
    playDOM.style.backgroundImage = 'url("./img/zanting.png")';
    musicNameDOM.innerText = songs[currentSongIndex].name;
    musicImgDOM.src = songs[currentSongIndex].photo;
    bodyDOM.background = ".img/" + songs[currentSongIndex].photo;
    musicImgDOM.style.animationPlayState = "running"

}

切换播放方式(单曲循环随机播放),具体实现下文我会通过进度条的判断来实现音乐循环随机播放。


selectionDOM.addEventListener('click', playModeSelection)

function playModeSelection() {

    if (selectionDOM.title == "循环播放") {
        selectionDOM.style.backgroundImage = 'url("../img/danquxunhuan.png")'
        selectionDOM.title = "单曲播放"
        audioDOM.loop = true;

    } else if (selectionDOM.title == "单曲播放") {
        selectionDOM.style.backgroundImage = 'url("../img/suijibofang.png")'
        selectionDOM.title = "随机播放";
        audioDOM.loop = false;

    } else if (selectionDOM.title == "随机播放") {
        selectionDOM.style.backgroundImage = 'url("../img/xunhuanbofang.png")'
        selectionDOM.title = "循环播放";
        audioDOM.loop = false;

    }
}

进度条的实现,点击进度条会跳转到指定的时间。给进度条一个计时器放到function play()里(在下文播放暂停的代码区),每隔一秒判断一次当前歌曲是否播放结束。

meterDOM.onclick = setProgress;

function setProgress(e) {
    var offsetLeft = (e.clientX - meterDOM.offsetLeft) / meterDOM.offsetWidth;
    audioDOM.currentTime = offsetLeft * audioDOM.duration;
    meterDOM.setAttribute('value', offsetLeft * 100)
}


function showProgress() {

    if (audioDOM.ended && selectionDOM.title == "随机播放") {
        console.log(Math.floor(Math.random() * songs.length))
        changeSong(Math.floor(Math.random() * songs.length))
    
    } else if (audioDOM.ended && selectionDOM.title == "循环播放") {
        changeSong(1)
    }

    meterDOM.setAttribute('value', audioDOM.currentTime / audioDOM.duration * 100);
}

音乐的时间。

/*歌曲时间
loadedmetadata:
当指定的音频/视频的元数据已加载时,会发生 loadedmetadata 事件。
音频/视频的元数据包括:时长、尺寸(仅视频)以及文本轨道。

timeupdate :
事件在音频/视频(audio/video)的播放位置发生改变时触发。


duration:
属性以秒或毫秒为单位指定过渡动画所需的时间。默认值为 0s
*/


audioDOM.addEventListener("loadedmetadata", function (event) {

    if (audioDOM.duration % 60 < 10) {
        tTimeDOM.innerHTML = parseInt(audioDOM.duration / 60) + ":0" + parseInt(audioDOM.duration % 60)

    } else {
        tTimeDOM.innerHTML = parseInt(audioDOM.duration / 60) + ":" + parseInt(audioDOM.duration % 60)
    }

});

audioDOM.addEventListener("timeupdate", function (event) {

    if (audioDOM.currentTime < 10) {
        cTimeDOM.innerHTML = "0:0" + Math.floor(audioDOM.currentTime);

    } else if (audioDOM.currentTime < 60) {
        cTimeDOM.innerHTML = "0:" + Math.floor(audioDOM.currentTime);

    } else {
        var minet = parseInt(audioDOM.currentTime / 60);
        var sec = audioDOM.currentTime - minet * 60;

        if (sec < 10) {
            cTimeDOM.innerHTML = "0" + minet + ":" + "0" + parseInt(sec);
        
        } else {
            cTimeDOM.innerHTML = "0" + minet + ":" + parseInt(sec);
        }
    }
});

音乐暂停和播放,里面添加了一个计时器用来实现进度实时变化。

/* 暂停 开始*/

var timer = null;
playDOM.addEventListener('click', play)

function play() {

    if (audioDOM.paused) {
        audioDOM.play()
        timer = setInterval(showProgress, 1000);
        playDOM.style.backgroundImage = 'url("./img/zanting.png")'
        playDOM.setAttribute("title", "暂停")
        musicImgDOM.style.animationPlayState = "running"

    } else {
        audioDOM.pause()
        playDOM.title = "播放"
        playDOM.style.backgroundImage = 'url("./img/bofang.png")'
        musicImgDOM.style.animationPlayState = "paused"

        clearInterval(timer)
    }
}

音乐音量的控制

/* 控制音量大小 */
slinceDOM.addEventListener("click", slince)

function slince() {

    if (slinceDOM.title == "静音") {
        audioDOM.muted = true
        slinceDOM.title = "非静音"
        slinceDOM.style.backgroundImage = 'url("../img/24gl-volumeDisable.png")'

    } else {
        audioDOM.muted = false
        slinceDOM.title = '静音'
        slinceDOM.style.backgroundImage = 'url("../img/24gl-volumeMiddle.png")'
    }
}

/*每点击一下,增加10%,如果超过最大就为1,超过最小就为0*/
riseDOM.addEventListener('click', function () {
    changeVol(0.1)
})
minusDOM.addEventListener('click', function () {
    changeVol(-0.1)
})

function changeVol(n) {

    if (audioDOM.volume + n < 0) {
        audioDOM.volume = 0;

    } else if (audioDOM.volume + n <= 1.0) {
        audioDOM.volume = audioDOM.volume + n;

    } else {
        audioDOM.volume = 1.0
    }
}

播放列表的动态实现

2023.3.25更新 添加每一次手动点击列表切换歌曲时重置进度条已加载的长度,添加一些li的样式。

/*播放列表*/
listDOM.addEventListener('click', showList)

function showList() {

    if (listDOM.title === "列表") {
        listALLDOM.style.display = "block";
        listDOM.title = "关闭播放列表";

    } else {
        listALLDOM.style.display = "none";
        listDOM.title = "列表";
    }
}


/*
querySelector() 方法返回文档中与指定选择器或选择器组匹配的第一个 Element对象。如果找不到匹配项,则返回null。
insertBefore() 方法在现有子节点之前插入子节点。

*/

var selectDOM = document.querySelector('.item').querySelector('ul');

for (var i = 0; i < songs.length; i++) {
    var li = document.createElement('li');
    li.innerHTML = songs[i].name;
    li.title = songs[i].name;
    li.style.height = "50px"
    li.style.fontSize = "32px"
    selectDOM.insertBefore(li, selectDOM.children[i]);
}

selectDOM.children[0].classList.add('firstMusic');

for (var i = 0; i < selectDOM.children.length; i++) {

    selectDOM.children[i].index = i;
    selectDOM.children[i].addEventListener('click', function (e) {

        for (var j = 0; j < selectDOM.children.length; j++) {
            selectDOM.children[j].classList.remove('firstMusic');
        }

        this.classList.add('firstMusic');

        meterDOM.setAttribute('value',0)
        changeSong(e.target.index);
    })
}

到这里就结束了,后续添加更多内容。

(第一次写博客,写的不好请谅解)。

完整JS代码

var audioDOM = document.getElementById("audio");
var collectDOM = document.getElementById("collect");
var selectionDOM = document.getElementById("selection");
var prevDOM = document.getElementById("prev");
var playDOM = document.getElementById("play");
var nextDOM = document.getElementById("next");
var slinceDOM = document.getElementById("slince");
var listDOM = document.getElementById("list");
var listALLDOM = document.getElementById("listALL");
var musicNameDOM = document.getElementById("musicName")
var musicImgDOM = document.getElementById("musicImg")
var tTimeDOM = document.getElementById("tTime")
var cTimeDOM = document.getElementById("cTime")
var meterDOM = document.getElementById("meter")
var bodyDOM = document.getElementById("body")
var riseDOM = document.getElementById("rise")
var minusDOM = document.getElementById("minus")


/*音乐*/
var songs = [

    {
        name: "周杰伦 - 半岛铁盒",
        photo: "../img/bandaotiehe.jpg"
    },
    {
        name: "周杰伦 - 外婆",
        photo: "../img/waipo.jpg"
    },
    {
        name: "周杰伦 - 完美主义",
        photo: "../img/wanmeizhuyi.jpg"
    },
    {
        name: "周杰伦 - 威廉古堡",
        photo: "../img/weiliangubao.jpg"
    },
    {
        name: "周杰伦 - 蜗牛",
        photo: "../img/woniu.jpg"
    },
    {
        name: "wake",
        photo: "../img/wake.jpg"
    },
    {
        name: "ceshi",
        photo: "../img/ceshi.png"
    }
]
musicNameDOM.innerText = songs[0].name
musicImgDOM.src = songs[0].photo




/*收藏*/
collectDOM.addEventListener('click', changeCollect)

function changeCollect() {
    if (collectDOM.title == "收藏") {
        collectDOM.style.backgroundImage = 'url("../img/shoucang.png")';
        collectDOM.setAttribute("title", "取消收藏");

    } else {
        collectDOM.style.backgroundImage = 'url("../img/icon_collect.png")';
        collectDOM.title = "收藏"

    }
}


/*播放方式*/




selectionDOM.addEventListener('click', playModeSelection)

function playModeSelection() {

    if (selectionDOM.title == "循环播放") {
        selectionDOM.style.backgroundImage = 'url("../img/danquxunhuan.png")'
        selectionDOM.title = "单曲播放"
        audioDOM.loop = true;

    } else if (selectionDOM.title == "单曲播放") {
        selectionDOM.style.backgroundImage = 'url("../img/suijibofang.png")'
        selectionDOM.title = "随机播放";
        audioDOM.loop = false;

    } else if (selectionDOM.title == "随机播放") {
        selectionDOM.style.backgroundImage = 'url("../img/xunhuanbofang.png")'
        selectionDOM.title = "循环播放";
        audioDOM.loop = false;

    }
}


/*播放 上一首播放 下一首播放*/
var currentSongIndex = 0;
var songsListLength = songs.length;
audioDOM.src = './mp3/' + songs[currentSongIndex].name + '.mp3'

nextDOM.addEventListener('click', next)

function next() {
    meterDOM.setAttribute('value',0)
    if (selectionDOM.title == "随机播放") {
        changeSong(Math.floor(Math.random() * songs.length))
    } else {
        changeSong(1.1)
    }
}

prevDOM.addEventListener('click', prev)

function prev() {
    meterDOM.setAttribute('value',0)
    if (selectionDOM.title == "随机播放") {
        changeSong(Math.floor(Math.random() * songs.length))
    } else {
        changeSong(-1.1)
    }
}


/* 暂停 开始*/

var timer = null;

playDOM.addEventListener('click', play)

function play() {

    if (audioDOM.paused) {
        audioDOM.play()

        timer = setInterval(showProgress, 1000);
        playDOM.style.backgroundImage = 'url("./img/zanting.png")'
        playDOM.setAttribute("title", "暂停")
        musicImgDOM.style.animationPlayState = "running"

    } else {
        audioDOM.pause()
        playDOM.title = "播放"
        playDOM.style.backgroundImage = 'url("./img/bofang.png")'
        musicImgDOM.style.animationPlayState = "paused"

        clearInterval(timers)

    }
}

meterDOM.onclick = setProgress;


function setProgress(e) {
    var offsetLeft = (e.clientX - meterDOM.offsetLeft) / meterDOM.offsetWidth;
    audioDOM.currentTime = offsetLeft * audioDOM.duration;
    meterDOM.setAttribute('value', offsetLeft * 100)

}

/*function changeModeMusic() {

    if (audioDOM.ended && selectionDOM.title == "随机播放") {
        console.log(Math.floor(Math.random() * songs.length))
        changeSong(Math.floor(Math.random() * songs.length))
    } else if (audioDOM.ended && selectionDOM.title == "循环播放") {
        changeSong(1)
    }

}*/


function showProgress() {

    if (audioDOM.ended && selectionDOM.title == "随机播放") {
        console.log(Math.floor(Math.random() * songs.length))
        changeSong(Math.floor(Math.random() * songs.length))
    } else if (audioDOM.ended && selectionDOM.title == "循环播放") {
        changeSong(1)
    }

    meterDOM.setAttribute('value', audioDOM.currentTime / audioDOM.duration * 100);
}


/*歌曲时间
loadedmetadata:
当指定的音频/视频的元数据已加载时,会发生 loadedmetadata 事件。
音频/视频的元数据包括:时长、尺寸(仅视频)以及文本轨道。

timeupdate :
事件在音频/视频(audio/video)的播放位置发生改变时触发。


duration:
属性以秒或毫秒为单位指定过渡动画所需的时间。默认值为 0s
*/


audioDOM.addEventListener("loadedmetadata", function (event) {
    if (audioDOM.duration % 60 < 10) {
        tTimeDOM.innerHTML = parseInt(audioDOM.duration / 60) + ":0" + parseInt(audioDOM.duration % 60)

    } else {
        tTimeDOM.innerHTML = parseInt(audioDOM.duration / 60) + ":" + parseInt(audioDOM.duration % 60)
    }
});

audioDOM.addEventListener("timeupdate", function (event) {


    if (audioDOM.currentTime < 10) {
        cTimeDOM.innerHTML = "0:0" + Math.floor(audioDOM.currentTime);

    } else if (audioDOM.currentTime < 60) {
        cTimeDOM.innerHTML = "0:" + Math.floor(audioDOM.currentTime);

    } else {
        var minet = parseInt(audioDOM.currentTime / 60);
        var sec = audioDOM.currentTime - minet * 60;

        if (sec < 10) {
            cTimeDOM.innerHTML = "0" + minet + ":" + "0" + parseInt(sec);

        } else {

            cTimeDOM.innerHTML = "0" + minet + ":" + parseInt(sec);
        }
    }
});


/*进度条*/


/* 控制音量大小 */
slinceDOM.addEventListener("click", slince)

function slince() {
    if (slinceDOM.title == "静音") {
        audioDOM.muted = true
        slinceDOM.title = "非静音"
        slinceDOM.style.backgroundImage = 'url("../img/24gl-volumeDisable.png")'


    } else {
        audioDOM.muted = false
        slinceDOM.title = '静音'
        slinceDOM.style.backgroundImage = 'url("../img/24gl-volumeMiddle.png")'
    }
}

riseDOM.addEventListener('click', function () {
    changeVol(0.1)
})
minusDOM.addEventListener('click', function () {
    changeVol(-0.1)
})

function changeVol(n) {
    if (audioDOM.volume + n < 0) {
        audioDOM.volume = 0;
    } else if (audioDOM.volume + n <= 1.0) {
        audioDOM.volume = audioDOM.volume + n;
    } else {
        audioDOM.volume = 1.0
    }
}


/*播放列表*/
listDOM.addEventListener('click', showList)

function showList() {
    if (listDOM.title === "列表") {
        listALLDOM.style.display = "block";
        listDOM.title = "关闭播放列表";


    } else {
        listALLDOM.style.display = "none";
        listDOM.title = "列表";
    }

}


/*
querySelector() 方法返回文档中与指定选择器或选择器组匹配的第一个 Element对象。如果找不到匹配项,则返回null。
insertBefore() 方法在现有子节点之前插入子节点。

*/

var selectDOM = document.querySelector('.item').querySelector('ul');
var li1 = document.createElement('li');

for (var i = 0; i < songs.length; i++) {
    var li = document.createElement('li');
    li.innerHTML = songs[i].name;
    li.title = songs[i].name;
    li.style.height = "50px"
    li.style.fontSize = "32px"
    selectDOM.insertBefore(li, selectDOM.children[i]);
}

selectDOM.children[0].classList.add('nowMusic');

for (var i = 0; i < selectDOM.children.length; i++) {

    selectDOM.children[i].index = i;
    selectDOM.children[i].addEventListener('click', function (e) {

        /*可写可不写???*/
/*        for (var j = 0; j < selectDOM.children.length; j++) {
            selectDOM.children[j].classList.remove('nowMusic');
        }*/

        this.classList.add('nowMusic');

        meterDOM.setAttribute('value',0)
        console.log(e.target.index)
        changeSong(e.target.index);
        playDOM.title = "暂停";

    })
}



/*切换歌曲*/
function changeSong(num) {

    if (num == 1.1 || num == -1.1){
        num = parseInt(num);
        currentSongIndex = (currentSongIndex + num + songsListLength) % songsListLength;
    }else {
        currentSongIndex = num;
    }

    audioDOM.src = './mp3/' + songs[currentSongIndex].name + '.mp3';

    for (let j = 0; j < selectDOM.children.length; j++) {
        selectDOM.children[j].classList.remove('nowMusic');
    }

    selectDOM.children[currentSongIndex].classList.add('nowMusic');

    audioDOM.play()
    playDOM.style.backgroundImage = 'url("./img/zanting.png")';
    musicNameDOM.innerText = songs[currentSongIndex].name;
    musicImgDOM.src = songs[currentSongIndex].photo;
    bodyDOM.background = ".img/" + songs[currentSongIndex].photo;
    musicImgDOM.style.animationPlayState = "running"

}






















/*
function changeSong(userNum) {


    if (userNum == 1.0 || userNum == -1.0){
        currentSongIndex = (currentSongIndex + num + songsListLength) % songsListLength;
    }else {
        currentSongIndex = userNum;
    }



    audioDOM.src = './mp3/' + songs[currentSongIndex].name + '.mp3';
    audioDOM.play()

    for (let j = 0; j < selectDOM.children.length; j++) {
        selectDOM.children[j].classList.remove('nowMusic');
    }

    selectDOM.children[currentSongIndex].classList.add('nowMusic');

    playDOM.style.backgroundImage = 'url("./img/zanting.png")';
    musicNameDOM.innerText = songs[currentSongIndex].name;
    musicImgDOM.src = songs[currentSongIndex].photo;
    bodyDOM.background = ".img/" + songs[currentSongIndex].photo;
    musicImgDOM.style.animationPlayState = "running"

}*/

  • 14
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是一个基本的原生JS音乐播放器,包含播放列表功能: HTML代码: ```html <div id="music-player"> <div class="player-controls"> <button id="play-pause-btn">播放</button> <input type="range" id="seek-slider" min="0" value="0"> <span id="current-time">0:00</span> / <span id="duration">0:00</span> <button id="prev-btn">上一首</button> <button id="next-btn">下一首</button> </div> <ul class="playlist"> <li data-src="path/to/song1.mp3">歌曲1</li> <li data-src="path/to/song2.mp3">歌曲2</li> <li data-src="path/to/song3.mp3">歌曲3</li> </ul> </div> ``` CSS代码: ```css #music-player { width: 500px; margin: 0 auto; } .player-controls { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; } .playlist { list-style: none; margin: 0; padding: 0; } .playlist li { cursor: pointer; padding: 5px; } .playlist li:hover { background-color: #f5f5f5; } ``` JS代码: ```js const musicPlayer = document.getElementById('music-player'); const playPauseBtn = musicPlayer.querySelector('#play-pause-btn'); const seekSlider = musicPlayer.querySelector('#seek-slider'); const currentTimeLabel = musicPlayer.querySelector('#current-time'); const durationLabel = musicPlayer.querySelector('#duration'); const prevBtn = musicPlayer.querySelector('#prev-btn'); const nextBtn = musicPlayer.querySelector('#next-btn'); const playlist = musicPlayer.querySelector('.playlist'); const audio = new Audio(); let currentSongIndex = 0; let playlistItems; // 初始化播放列表 function initPlaylist() { playlistItems = playlist.querySelectorAll('li'); playlistItems.forEach((item, index) => { item.addEventListener('click', () => { currentSongIndex = index; playSong(currentSongIndex); }); }); } // 播放/暂停按钮事件处理函数 function togglePlayPause() { if (audio.paused) { playPauseBtn.textContent = '暂停'; audio.play(); } else { playPauseBtn.textContent = '播放'; audio.pause(); } } // 上一首按钮事件处理函数 function playPrevSong() { currentSongIndex--; if (currentSongIndex < 0) { currentSongIndex = playlistItems.length - 1; } playSong(currentSongIndex); } // 下一首按钮事件处理函数 function playNextSong() { currentSongIndex++; if (currentSongIndex >= playlistItems.length) { currentSongIndex = 0; } playSong(currentSongIndex); } // 播放指定索引的歌曲 function playSong(index) { const songSrc = playlistItems[index].getAttribute('data-src'); audio.src = songSrc; audio.load(); audio.play(); playPauseBtn.textContent = '暂停'; } // 更新播放进度条和当前时间标签 function updateProgress() { seekSlider.value = audio.currentTime; const currentMinutes = Math.floor(audio.currentTime / 60); const currentSeconds = Math.floor(audio.currentTime % 60); currentTimeLabel.textContent = `${currentMinutes}:${currentSeconds.toString().padStart(2, '0')}`; } // 初始化音乐播放器 function initPlayer() { initPlaylist(); audio.addEventListener('loadedmetadata', () => { const totalMinutes = Math.floor(audio.duration / 60); const totalSeconds = Math.floor(audio.duration % 60); durationLabel.textContent = `${totalMinutes}:${totalSeconds.toString().padStart(2, '0')}`; seekSlider.max = audio.duration; }); audio.addEventListener('timeupdate', updateProgress); playPauseBtn.addEventListener('click', togglePlayPause); prevBtn.addEventListener('click', playPrevSong); nextBtn.addEventListener('click', playNextSong); seekSlider.addEventListener('input', () => { audio.currentTime = seekSlider.value; }); playSong(currentSongIndex); } initPlayer(); ``` 这段代码实现了基本的音乐播放器功能,包括播放/暂停、上一首/下一首播放进度条播放列表功能。你可以根据自己的需求进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值