实现简易音乐播放器-PartFour

实现上一曲、下一曲

  现在,为音乐列表设置切换到上一曲和切换到下一曲的功能;在页面中会用到该功能的部分为上一曲按钮、下一曲按钮、音乐结束时自动切换到下一曲。
  在播放列表的每一项中添加 data-index 属性来记录其在播放列表中的顺序,对 <audio> 标签设置 data-index 属性来标记当前为播放列表中的第几首曲目。通过读取 data-index 属性来计算出该播放曲目的顺序,上一首、下一首该播放曲目的顺序。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>MusicControl</title>
    <style>
        html {
            box-sizing: border-box;
        }

        *,
        *::before,
        *::after {
            box-sizing: inherit;
        }

        .control-button {
            margin-top: 10px;
            margin-left: 20px;
        }

        .clear-both::after {
            content: '';
            display: block;
            clear: both;
        }

        .play-control-button {
            width: 64px;
            height: 64px;
            background-image: url(icons.png);
            float: left;
            margin-right: 10px;
            cursor: pointer;
        }

        .prev {
            background-position: 0 0;
        }

        .next {
            background-position: 0 -64px;
        }

        .play {
            background-position: 0 -192px;
        }

        .pause {
            background-position: 0 -128px;
        }
        

        .control-bar {
            margin-top: 20px;
            margin-left: 20px;
        }

        .controlTime {
            float: left;
            color: #ccc;
        }

        .play-control-progress {
            position: relative;
            margin-left: 8px;
            margin-right: 8px;
            margin-top: 8px;
            float: left;
            display: block;
            width: 300px;
            height: 5px;
            background-color: #ccc;
        }

        .playing-progress {
            position: absolute;
            display: block;
            height: 100%;
            width: 0%;
            background-color: #2f9842;
        }

        .playing-bar {
            position: absolute;
            margin-top: -1.5px;
            margin-left: -4px;
            width: 8px;
            height: 8px;
            background-color: #2f9842;
            border: 0.5px solid #000;
            border-radius: 50%
        }

        .music-list li {
            display: block;
            list-style: none;
            padding-bottom: 10px;
            cursor: pointer;
        }

    </style>
</head>
<body>
    <audio id="music" src="" data-index="0"></audio>
    <div class="control-button clear-both">
        <div class="play-control-button prev" id="controlOne"></div>
        <div class="play-control-button play" id="controlTwo"></div>
        <div class="play-control-button next" id="controlThree"></div>
    </div>
    <div class="control-bar clear-both">
        <span class="controlTime" id="nowTime">00:00</span>
        <div class="play-control-progress" id="controlProgress">
            <div class="playing-progress" id="playingProgress"></div>
            <div class="playing-bar" id="playingBar"></div>
        </div>
        <span class="controlTime" id="endTime">00:00</span>
    </div>
    <div>
        <ul class="music-list clear-both" id="musicList">
        </ul>
    </div>
    <script>
        window.onload = function() {
            let music = document.getElementById('music');
            
            let controlOne = document.getElementById('controlOne');
            let controlTwo = document.getElementById('controlTwo');
            let controlThree = document.getElementById('controlThree');
            
            let controlProgress = document.getElementById('controlProgress');
            let playingProgress = document.getElementById('playingProgress');
            let playingBar = document.getElementById('playingBar');
            
            let nowTime = document.getElementById('nowTime');
            let endTime = document.getElementById('endTime');

            let musicList = document.getElementById('musicList');

            let drag = 0;
            let flag = 0;

            nowTime.innerText = "00:00";

            function getMin(min) {
                let res = parseInt(min / 60);
                if(res < 10) {
                    return '0' + res;
                } else {
                    return res + '';
                }
            }

            function getSec(min) {
                let res = parseInt(min % 60);
                if(res < 10) {
                    return '0' + res;
                } else {
                    return res + '';
                }
            }

            let timer = '';
            let stop = '';

            let dragTime = 0;

            function musicPlay() {
                music.play();
                timer = setInterval(() => {
                    let progressLen = music.currentTime / music.duration * controlProgress.clientWidth;
                    nowTime.innerText = getMin(music.currentTime) + ":" + getSec(music.currentTime);
                    playingProgress.style.width = progressLen + 'px';
                    playingBar.style.marginLeft = progressLen - 4 + 'px';
                },1000);
            }

            function musicPause() {
                music.pause();
                clearInterval(timer);
            }

            class musicObj {
                constructor(name, src, author, time) {
                    this.name = name;
                    this.src = src;
                    this.author = author;
                    this.time = time;
                }
            };

            let musicNameList = ['MusicOne', 'MusicTwo', 'MusicThree'];
            let musicSrcLsit = ['Demo0.mp3', 'Demo1.mp3', 'Demo2.mp3'];
            let musicAuthorList = ['AuthorOne', 'AuthorTwo', 'AuthorThree'];
            let musicTimeList = ['04:01', '02:00', '03:40'];

            let musicListObj = new Array();

            for(let i in musicNameList) {
                musicListObj[i] = new musicObj(musicNameList[i], musicSrcLsit[i], musicAuthorList[i], musicTimeList[i]);
            }

            function playPrev() {
                let dataIndex = parseInt(music.getAttribute('data-index'));
                let prevIndex = (dataIndex - 1) < 0 ? musicListObj.length - 1 : (dataIndex - 1);
                musicPause();
                music.setAttribute('src', musicListObj[prevIndex].src);
                music.setAttribute('data-index', prevIndex);
                music.currentTime = 0;
                nowTime.innerText = "00:00";
                endTime.innerText = musicListObj[prevIndex].time;
                controlTwo.className = "play-control-button pause";
                playingProgress.style.width = 0 + 'px';
                playingBar.style.marginLeft = 0 + 'px';
                musicPlay();
            }

            function playNext() {
                let dataIndex = parseInt(music.getAttribute('data-index'));
                let nextIndex = (dataIndex + 1) > (musicListObj.length - 1) ? 0 : (dataIndex + 1)
                musicPause();
                music.setAttribute('src', musicListObj[nextIndex].src);
                music.setAttribute('data-index', nextIndex);
                music.currentTime = 0;
                nowTime.innerText = "00:00";
                endTime.innerText = musicListObj[nextIndex].time;
                controlTwo.className = "play-control-button pause";
                playingProgress.style.width = 0 + 'px';
                playingBar.style.marginLeft = 0 + 'px';
                musicPlay();
            }

            for(let i in musicListObj) {
                let newNode = document.createElement('li');
                newNode.setAttribute('data-src', musicListObj[i].src);
                newNode.setAttribute('data-time', musicListObj[i].time);
                newNode.setAttribute('data-index', i);
                newNode.innerText = musicListObj[i].name + ' - ' + musicListObj[i].author;
                musicList.appendChild(newNode);
            }

            controlTwo.addEventListener('click', () => {
                console.log("Click");
                if(controlTwo.className == "play-control-button play") {
                    controlTwo.className = "play-control-button pause";
                    musicPlay();
                } else if (controlTwo.className == "play-control-button pause") {
                    controlTwo.className = "play-control-button play";
                    musicPause();
                }
            });

            controlProgress.addEventListener('click', (e) => {
                e = e || window.e;
                let rate = ((e.clientX - controlProgress.getBoundingClientRect().left) / controlProgress.clientWidth);
                let progressLen = e.clientX - controlProgress.getBoundingClientRect().left;
                playingProgress.style.width = progressLen + 'px';
                playingBar.style.marginLeft = progressLen - 4 + 'px';
                let theTime = parseInt(rate * (music.duration))
                music.currentTime = theTime;
                nowTime.innerText = getMin(theTime) + ":" + getSec(theTime);
                console.log(rate);
            });

            playingBar.addEventListener('mousedown', () => {
                console.log('mousedown');
                drag = 1;
                flag = 1;
                clearInterval(timer);
            });

            document.addEventListener('mouseup', () => {
                console.log('mouseup');
                drag = 0;
                if(flag == 1) {
                    music.currentTime = dragTime;
                    timer = setInterval(() => {
                        let progressLen = music.currentTime / music.duration * controlProgress.clientWidth;
                        nowTime.innerText = getMin(music.currentTime) + ":" + getSec(music.currentTime);
                        playingProgress.style.width = progressLen + 'px';
                        playingBar.style.marginLeft = progressLen - 4 + 'px';
                    },1000);
                    console.log('reStart');
                }
                flag = 0;
            });

            controlProgress.addEventListener('mousemove', (e) => {
                e = e || window.e;
                if(drag == 1) {
                    console.log('mousemove');
                    let progressLen = e.clientX - controlProgress.getBoundingClientRect().left;
                    let rate = (progressLen / controlProgress.clientWidth);
                    playingProgress.style.width = progressLen + 'px';
                    playingBar.style.marginLeft = progressLen - 4 + 'px';
                    let theTime = parseInt(rate * (music.duration));
                    nowTime.innerText = getMin(theTime) + ":" + getSec(theTime);
                    dragTime = theTime;
                }
            });

            musicList.addEventListener('click', (e) => {
                e = e || window.e;
                let musicSrc = e.target.getAttribute('data-src');
                let dataIndex = e.target.getAttribute('data-index');
                musicPause();
                music.setAttribute('src', musicSrc);
                music.setAttribute('data-index', dataIndex);
                music.currentTime = 0;
                endTime.innerText =  e.target.getAttribute('data-time');
                musicPlay();
                e.stopPropagation();
            });

            controlOne.addEventListener('click', () => {
                playPrev();
            });

            controlThree.addEventListener('click', () => {
                playNext();
            });

            music.addEventListener('ended', () => {
                playNext();
            });

            music.src = musicListObj[0].src;
            endTime.innerText = musicListObj[0].time;

        }
    </script>
</body>
</html>

  为防止因先使用后定义而造成的变量提升,将代码整理为定义在前,操作在后的格式。
  
  

播放歌曲记录功能

  使用浏览器的持久储存 window.localStorage 来储存当前播放的歌曲,使得可以在页面重新载入后依然从该歌曲播放而不是重新从播放列表的第一首歌曲开始播放。
  本例中使用 window.localStorage.setItem(key, value) 来将数据(键值对)写入浏览器的持久储存中;使用 window.loacalStorage.getItem(key) 来读取浏览器持久储存中对应的数据。

    <script>
        window.onload = function() {
            
            let index = window.localStorage.getItem('musicId') ? window.localStorage.getItem('musicId') : 0;
            
            let music = document.getElementById('music');
            
            let controlOne = document.getElementById('controlOne');
            let controlTwo = document.getElementById('controlTwo');
            let controlThree = document.getElementById('controlThree');
            
            let controlProgress = document.getElementById('controlProgress');
            let playingProgress = document.getElementById('playingProgress');
            let playingBar = document.getElementById('playingBar');
            
            let nowTime = document.getElementById('nowTime');
            let endTime = document.getElementById('endTime');

            let musicList = document.getElementById('musicList');

            let drag = 0;
            let flag = 0;

            nowTime.innerText = "00:00";

            function getQueryString(str) {
                let reg = new RegExp("(^|&)" + str + "=([^&]*)(&|$)");
                let r = window.location.search.substr(1).match(reg);
                if (r != null) {
                    return unescape(r[2]);
                } else {
                    return null;
                }
            }

            function getMin(min) {
                let res = parseInt(min / 60);
                if(res < 10) {
                    return '0' + res;
                } else {
                    return res + '';
                }
            }

            function getSec(min) {
                let res = parseInt(min % 60);
                if(res < 10) {
                    return '0' + res;
                } else {
                    return res + '';
                }
            }

            let timer = '';
            let stop = '';

            let dragTime = 0;

            function musicPlay() {
                music.play();
                window.localStorage.setItem('musicId', music.getAttribute('data-index'));
                timer = setInterval(() => {
                    let progressLen = music.currentTime / music.duration * controlProgress.clientWidth;
                    nowTime.innerText = getMin(music.currentTime) + ":" + getSec(music.currentTime);
                    playingProgress.style.width = progressLen + 'px';
                    playingBar.style.marginLeft = progressLen - 4 + 'px';
                },1000);
            }

            function musicPause() {
                music.pause();
                clearInterval(timer);
            }

            class musicObj {
                constructor(name, src, author, time) {
                    this.name = name;
                    this.src = src;
                    this.author = author;
                    this.time = time;
                }
            };

            let musicNameList = ['MusicOne', 'MusicTwo', 'MusicThree'];
            let musicSrcLsit = ['Demo0.mp3', 'Demo1.mp3', 'Demo2.mp3'];
            let musicAuthorList = ['AuthorOne', 'AuthorTwo', 'AuthorThree'];
            let musicTimeList = ['04:01', '02:00', '03:40'];

            let musicListObj = new Array();

            for(let i in musicNameList) {
                musicListObj[i] = new musicObj(musicNameList[i], musicSrcLsit[i], musicAuthorList[i], musicTimeList[i]);
            }

            function playPrev() {
                let dataIndex = parseInt(music.getAttribute('data-index'));
                let prevIndex = (dataIndex - 1) < 0 ? musicListObj.length - 1 : (dataIndex - 1);
                musicPause();
                music.setAttribute('src', musicListObj[prevIndex].src);
                music.setAttribute('data-index', prevIndex);
                music.currentTime = 0;
                nowTime.innerText = "00:00";
                endTime.innerText = musicListObj[prevIndex].time;
                controlTwo.className = "play-control-button pause";
                playingProgress.style.width = 0 + 'px';
                playingBar.style.marginLeft = 0 + 'px';
                musicPlay();
            }

            function playNext() {
                let dataIndex = parseInt(music.getAttribute('data-index'));
                let nextIndex = (dataIndex + 1) > (musicListObj.length - 1) ? 0 : (dataIndex + 1)
                musicPause();
                music.setAttribute('src', musicListObj[nextIndex].src);
                music.setAttribute('data-index', nextIndex);
                music.currentTime = 0;
                nowTime.innerText = "00:00";
                endTime.innerText = musicListObj[nextIndex].time;
                controlTwo.className = "play-control-button pause";
                playingProgress.style.width = 0 + 'px';
                playingBar.style.marginLeft = 0 + 'px';
                musicPlay();
            }

            for(let i in musicListObj) {
                let newNode = document.createElement('li');
                newNode.setAttribute('data-src', musicListObj[i].src);
                newNode.setAttribute('data-time', musicListObj[i].time);
                newNode.setAttribute('data-index', i);
                newNode.innerText = musicListObj[i].name + ' - ' + musicListObj[i].author;
                musicList.appendChild(newNode);
            }

            controlTwo.addEventListener('click', () => {
                console.log("Click");
                if(controlTwo.className == "play-control-button play") {
                    controlTwo.className = "play-control-button pause";
                    musicPlay();
                } else if (controlTwo.className == "play-control-button pause") {
                    controlTwo.className = "play-control-button play";
                    musicPause();
                }
            });

            controlProgress.addEventListener('click', (e) => {
                e = e || window.e;
                let rate = ((e.clientX - controlProgress.getBoundingClientRect().left) / controlProgress.clientWidth);
                let progressLen = e.clientX - controlProgress.getBoundingClientRect().left;
                playingProgress.style.width = progressLen + 'px';
                playingBar.style.marginLeft = progressLen - 4 + 'px';
                let theTime = parseInt(rate * (music.duration))
                music.currentTime = theTime;
                nowTime.innerText = getMin(theTime) + ":" + getSec(theTime);
                console.log(rate);
            });

            playingBar.addEventListener('mousedown', () => {
                console.log('mousedown');
                drag = 1;
                flag = 1;
                clearInterval(timer);
            });

            document.addEventListener('mouseup', () => {
                console.log('mouseup');
                drag = 0;
                if(flag == 1) {
                    music.currentTime = dragTime;
                    timer = setInterval(() => {
                        let progressLen = music.currentTime / music.duration * controlProgress.clientWidth;
                        nowTime.innerText = getMin(music.currentTime) + ":" + getSec(music.currentTime);
                        playingProgress.style.width = progressLen + 'px';
                        playingBar.style.marginLeft = progressLen - 4 + 'px';
                    },1000);
                    console.log('reStart');
                }
                flag = 0;
            });

            controlProgress.addEventListener('mousemove', (e) => {
                e = e || window.e;
                if(drag == 1) {
                    console.log('mousemove');
                    let progressLen = e.clientX - controlProgress.getBoundingClientRect().left;
                    let rate = (progressLen / controlProgress.clientWidth);
                    playingProgress.style.width = progressLen + 'px';
                    playingBar.style.marginLeft = progressLen - 4 + 'px';
                    let theTime = parseInt(rate * (music.duration));
                    nowTime.innerText = getMin(theTime) + ":" + getSec(theTime);
                    dragTime = theTime;
                }
            });

            musicList.addEventListener('click', (e) => {
                e = e || window.e;
                let musicSrc = e.target.getAttribute('data-src');
                let dataIndex = e.target.getAttribute('data-index');
                musicPause();
                music.setAttribute('src', musicSrc);
                music.setAttribute('data-index', dataIndex);
                music.currentTime = 0;
                endTime.innerText =  e.target.getAttribute('data-time');
                musicPlay();
                e.stopPropagation();
            });

            controlOne.addEventListener('click', () => {
                playPrev();
            });

            controlThree.addEventListener('click', () => {
                playNext();
            });

            music.addEventListener('ended', () => {
                playNext();
            });

            music.src = musicListObj[index].src;
            music.setAttribute('data-index', index);
            endTime.innerText = musicListObj[index].time;

        }
    </script>

  开始时对作为音乐顺序的 index 进行初始化(判断该页面是否第一次被载入);通过 index 来判断应该加载的歌曲。在音乐播放函数 musicPlay() 中写入目前正在播放的音乐在播放列表中的顺序(也可以在定时函数中将当前播放时间也写入,这样下一次可以从断点中继续播放)。
  
  

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容