javascript
JavaScript + Audio API自制简易音乐播放器(详细完整版、小白都能看懂)
JavaScript + Audio API自制簡易音樂播放器(詳細完整版)
**
音樂播放器的功能清單如下:
**
1.點擊暫停按鈕,歌曲暫停
2.點擊播放按鈕,歌曲播放
3.單曲循環與取消單曲循環
4.當播放到列表最后一首歌曲時,點擊下一首自動切換到列表中的第一首
5.當播放到列表第一首歌曲時,點擊上一首自動切換到列表中的最后一首
6.一鍵靜音與非靜音
7.增大減小音量(既可通過鼠標點擊操作,也可通過鍵盤上下鍵操作)
8.下一首、上一首
9.快進、快退
10.進度條隨這音樂播放實時變化
11.歌曲已播放時長實時變化
12.點擊進度條區域可以進行快進快退,已播放時長和進度條的進度也同步更新
13.鼠標點擊拖動進度條的紅點(小方塊)可以進行快進快退,已播放時長和進度條的進度也同步更新
首先來看一下效果圖:
這是我的目錄結構:
JavaScript部分的難點:
1.多媒體事件的運用
2.獲取Dom對象
3.設置flag記錄true false的小技巧,來達到在同一個元素上點擊,出現不同的效果
4.鼠標事件的靈活運用
5.通過Dom對象動態修改樣式
6.設置定時器
7.鍵盤事件
CSS部分難點:
1.漸變色
2.pointer-events: none;可以讓某個元素實現類似于海市蜃樓的效果,具體理解為,你可以看的到某個元素,但是你無法摸的著。
3.相對定位
4.絕對定位
5.flex彈性盒子布局
6.精靈圖background屬性的靈活運用
7.屬性zoom: 0.2; 強制縮放
zoom牽一發動全身,zoom:0.5后 ,width和height都會變成原來的一半 ;
而transform: scale(0.5) div height200px,width:200px, scale(0.5)即為縮小為原來的一半時,他的height和width還是200px, 只不過里面的元素縮小了而已。
page.js部分的代碼如下:
var arrys = ["./songs/晴天 周杰倫.mp3","./songs/時間停了 鹿晗.mp3","./songs/光輝歲月 Beyon.mp3","./songs/梔子花開 何炅.mp3","./songs/紙短情長 煙把兒樂隊.mp3" ];var audio = document.createElement("audio"); audio.src = arrys[0]; // 多媒體(Media)事件: // canplaythrough 事件在視頻/音頻(audio/video)可以正常播放且無需停頓和緩沖時觸發。 // durationchange 事件在視頻/音頻(audio/video)的時長發生變化時觸發。 // pause 事件在視頻/音頻(audio/video)暫停時觸發。 // play 事件在視頻/音頻(audio/video)開始播放時觸發。 // volumechange 事件在音量發生改變時觸發。 // ended 事件在視頻/音頻(audio/video)播放結束時觸發。 // error 事件在視頻/音頻(audio/video)數據加載期間發生錯誤時觸發。 // canplay 事件在用戶可以開始播放視頻/音頻(audio/video)時觸發。 // timeupdate 事件在當前的播放位置發送改變時觸發。audio.addEventListener("canplaythrough", function() {console.log('music ready'); }, false); audio.addEventListener("timeupdate", showTime, true);function showTime() {duration = formatTime(audio.duration);currenttime = formatTime(audio.currentTime);document.getElementById('totaltime').innerHTML = duration.M + ':' + duration.S;document.getElementById('currenttime').innerHTML = currenttime.M + ':' + currenttime.S;//獲取當前播放的百分比 當前進度/總進度var percent = audio.currentTime / audio.duration//拼接進度條的widthvar swidth = (percent * 255) + "px";//設置進度條的播放進度document.getElementById("bar").style.width = swidth;document.getElementById("dot").style.left = swidth; } // 播放 function aPlay() {audio.play(); } // 暫停 function aPause() {audio.pause(); } // 快進 function go() {audio.currentTime += 10;audio.play();runToPause(); } // 快退 function back() {audio.currentTime -= 10;audio.play();runToPause(); }// 將播放圖標切換為暫停圖標 function runToPause(){runDom[0].style.display = 'none';pauseDom[0].style.display = 'inline-block'; } // 將暫停圖標切換為播放圖標 function PauseToRun(){runDom[0].style.display = 'inline-block';pauseDom[0].style.display = 'none'; }quietDom = document.getElementsByClassName('quiet'); noquietDom = document.getElementsByClassName('noquiet'); // 將靜音圖標切換為非靜音圖標 function quietToNo(){quietDom[0].style.display = 'none';noquietDom[0].style.display = 'inline-block'; }// 將非靜音圖標切換為靜音圖標 function noToquiet(){quietDom[0].style.display = 'inline-block';noquietDom[0].style.display = 'none'; }// 增大音量 function add() {audio.volume != 1 ? audio.volume += 0.1 : 1;console.log(audio.volume);if (audio.volume >= 0.001) {quietToNo();console.log('noquiet')} }// 減小音量 function subtract() {audio.volume != 0 ? audio.volume -= 0.1 : 0;console.log(audio.volume);if (audio.volume <= 0.001) {noToquiet();console.log('quiet')} }// 靜音 var qFlag = 0; // 是否靜音 function isquiet() {qFlag = !qFlag;// if(qFlag){// audio.volume = 0; // console.log(audio.volume);// }else{// audio.volume = 0.5;// } audio.volume = !audio.volume;} // 靜音圖標切換為非靜音圖標 function quiet() {quietToNo();isquiet(); }// 非靜音圖標切換為靜音圖標 function noquiet() {noToquiet();isquiet(); }// 時間格式轉換 function formatTime(seconds) {var h = 0,i = 0,s = Math.floor(seconds);h = Math.floor(s / 3600);i = Math.floor((s % 3600) / 60);s = s % 3600 % 60;return {H: h = h < 10 ? "0" + h : h,M: i = i < 10 ? "0" + i : i,S: s = s < 10 ? "0" + s : s}; };//設置播放源 var currMp3 = arrys[0]; //上一曲,并實現循環播放 function prev() {tmpMp3 = "";arrys.forEach(function(item, index) {// 通過循環找到與當前播放的音樂相同的那一個item,目的是為了拿到當前的indexif (item == currMp3) {if (index == 0) {tmpMp3 = arrys[arrys.length - 1];} else {//下一個tmpMp3 = arrys[index - 1];}console.log(tmpMp3)audio.src = tmpMp3;setTimeout(function() {audio.play()currMp3 = tmpMp3;}, 500)return;}})run(); // 把播放圖標切換成暫停圖標并播放音樂 }// 下一曲,并實現循環播放 function next() {tmpMp3 = "";arrys.forEach(function(item, index) {if (item == currMp3) { // 當找到當前播放的歌曲時,進入if代碼執行塊if ((index + 1) == arrys.length) {//說明是最后一個tmpMp3 = arrys[0];} else {//下一個tmpMp3 = arrys[index + 1];}console.log(tmpMp3)audio.src = tmpMp3;setTimeout(function() { // 設置定時器,在點擊下一曲按鈕時生效,audio.play(); // play() 方法開始播放當前的音頻或視頻。currMp3 = tmpMp3; // 將當前播放音樂的路徑更新到currMp3中保存}, 500)return;}})run(); // 把播放圖標切換成暫停圖標,并播放音樂 }var flag = 0; // 是否點擊了單曲循環按鈕,點了為1,沒點為0 // 當前歌曲播放完后,自動切換下一首 audio.addEventListener('ended', function() {if (flag) {arrys.forEach(function(item, index) {if (item == currMp3) {tmpMp3 = arrys[index]}setTimeout(function() {audio.play()currMp3 = tmpMp3;}, 500)})} else {next();} }, false);// 實現單曲循環 function circle() {console.log('單曲循環')flag = !flag; // 是否點擊了單曲循環按鈕,點了為1,沒點為0console.log(flag); }document.onkeyup = function(event) { //鍵盤事件var vol = 0.1; //1代表100%音量,每次增減0.1var time = 10; //單位秒,每次增減10秒// console.log("keyCode:" + event.keyCode);console.log("volume" + audio.volume);var e = event || window.event || arguments.callee.caller.arguments[0];// 鍵盤事件: // 屬性 描述 DOM // keydown 某個鍵盤按鍵被按下。 // keypress 某個鍵盤按鍵被按下并松開。 // keyup 某個鍵盤按鍵被松開。//實現鍵盤按上下鍵控制音樂的音量,按左右鍵控制音樂的快進快退if (e && e.keyCode === 38) {// 按 向上鍵audio.volume !== 1 ? audio.volume += vol : 1;if (audio.volume >= 0.001) {quietToNo();console.log('noquiet')}return false;} else if (e && e.keyCode === 40) {// 按 向下鍵audio.volume !== 0 ? audio.volume -= vol : 1;if (audio.volume <= 0.001) {noToquiet();console.log('quiet')}return false;} else if (e && e.keyCode === 37) {// 按 向左鍵audio.currentTime !== 0 ? audio.currentTime -= time : 1;return false;} else if (e && e.keyCode === 39) {// 按 向右鍵audio.volume !== audio.duration ? audio.currentTime += time : 1;return false;} else if (e && e.keyCode === 32) {// 按空格鍵 判斷當前是否暫停audio.paused === true ? audio.play() : audio.pause();if (audio.paused === false) {runToPause();} else {pauseToRun();}return false;}}; runDom = document.getElementsByClassName('run'); pauseDom = document.getElementsByClassName('pause'); // 點擊播放按鈕切換為暫停按鈕 function run() {runToPause();aPlay(); } // 暫停按鈕切換為播放按鈕 function pause() {PauseToRun();aPause(); }// 鼠標事件: // onclick 當用戶點擊某個對象時調用的事件句柄。 // ondblclick 當用戶雙擊某個對象時調用的事件句柄。 // onmousedown 鼠標左鍵被按下。 // onmouseenter 當鼠標指針移動到元素上時觸發。 // onmouseleave 當鼠標指針移出元素時觸發 // onmousemove 鼠標被移動。 // onmouseover 鼠標移到某元素之上。 // onmouseout 鼠標從某元素移開。 // onmouseup 鼠標左鍵被松開。window.onload = function() {var scrollDom = document.getElementById('scroll');var barDom = document.getElementById('bar');var dotDom = document.getElementById('dot');// 鼠標左鍵被按下。scrollDom.onmousedown = function(event) {// console.log("111" + event.offsetX);// 鼠標被移動scrollDom.onmousemove = function(event) {// console.log(event.offsetX);// console.log("offsetLeft" + event.offsetLeft)barDom.style.width = event.offsetX + "px";dotDom.style.left = (event.offsetX) + "px";pause();}}// 鼠標移到某元素上scrollDom.onmouseover = function() {scrollDom.onmousemove = null;}// 鼠標左鍵被松開scrollDom.onmouseup = function(e) {scrollDom.onmousemove = null; //鼠標左鍵松開后不做任何操作currentX = e.offsetX;var oWidth = scrollDom.offsetWidth; // 元素整體寬度 :邊框+內容區var cWidth = scrollDom.clientWidth; // 元素內容區寬度 :內容區var percents = (currentX / cWidth).toFixed(2);// console.log(percents + '%!')audio.currentTime = audio.duration * percents;run();}scrollDom.onclick = function(e) {console.log(e.offsetX);currentX = e.offsetX;barDom.style.width = e.offsetX + "px";dotDom.style.left = (e.offsetX) + "px";var oWidth = scrollDom.offsetWidth; // 元素整體寬度 :邊框+內容區var cWidth = scrollDom.clientWidth; // 元素內容區寬度 :內容區var percents = (currentX / cWidth).toFixed(2);// console.log(percents + '%')// console.log(audio.duration * percents)// console.log(formatTime(audio.duration * percents))audio.currentTime = audio.duration * percents;}}index.html部分的代碼如下:
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>簡易音樂播放器</title><link rel="stylesheet" href="./css/style.css"><script src="./js/page.js"></script></head><body><div id="all"><div class="speed"><div class="back" οnclick="back()" id="back" title="快退"></div><div class="go" οnclick="go()" id="go" title="快進"></div></div><div class="players"><div class="container clearfix"><div class="left clearfix"><div class="prev" οnclick="prev()" title="上一首"></div><div class="run" οnclick="run();" title="播放"></div><div class="pause" οnclick="pause();" title="暫停"></div><div class="next" οnclick="next()" title="下一首"></div></div><div class="middle"><div class="scroll" id="scroll"><div class="bar" id="bar"><div class="dot" id="dot"></div></div></div><div class="music_detail"><div id="currenttime">00:00</div><div class="line"> / </div><div id="totaltime">00:00</div></div></div><div class="right"><div class="circle" οnclick="circle()" title="單曲循環"></div><div class="quiet" οnclick="quiet()" id="quiet" title="取消靜音"></div><div class="noquiet" οnclick="noquiet()" id="noquiet" title="靜音"></div><div class="verticle"><div class="add" οnclick="add()" id="add" title="增加音量"></div><div class="subtract" οnclick="subtract()" id="subtract" title="減小音量"></div></div></div></div></div></div></body> </html>style.css部分的代碼如下:
#progressBar {width: 80%;height: 32%;background: #e9e9e9;position: relative; }#playProgressBar {position: absolute;top: 0;left: 0;background: #20bfd8;height: 100%;width: 100%; }#ptxt {width: 100%;height: 30px;text-align: center;font-size: 16px;line-height: 30px;z-index: 10;position: absolute; }* {margin: 0;padding: 0; }body {margin: 0 auto; } .speed{display: flex;align-items: center;justify-content: center; } #all{margin: 200px; }.clearfix:after {content: '';display: block;visibility: none;clear: both; }/* 播放圖標 */ .run {display: inline-block;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -267px -20px;zoom: 0.3;}/* float: left; */ /* zoom牽一發動全身,zoom:0.5后 ,width和height都會變成原來的一半 */ /*而transform: scale(0.5) div height200px,width:200px, scale(0.5)即為縮小為原來的一半時,他的height和width還是200px, 只不過里面的元素縮小了而已。 *//* 暫停圖標 */ .pause {display: none;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -517px -517px;zoom: 0.3; }/* zoom牽一發動全身,zoom:0.5后 ,width和height都會變成原來的一半 */ /*而transform: scale(0.5) div height200px,width:200px, scale(0.5)即為縮小為原來的一半時,他的height和width還是200px, 只不過里面的元素縮小了而已。 *//* 下一首圖標 */ .next {display: inline-block;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -765px -266px;zoom: 0.2; }/* 上一首圖標 */ .prev {display: inline-block;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -14px -271px;zoom: 0.2; }/* 單曲循環圖標 */ .circle {display: inline-block;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -514px -23px;zoom: 0.2; }/* 增大音量圖標 */ .add {display: inline-block;width: 90px;height: 90px;background-image: url(../img/voice.jpg);background-position: -163px -125px;zoom: 0.25; }/* 減小音量圖標 */ .subtract {display: inline-block;width: 90px;height: 90px;background-image: url(../img/voice.jpg);background-position: -37px -125px;zoom: 0.25; }/* 靜音圖標 */ .quiet {display: none;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -517px -762px;zoom: 0.2; }/* 非靜音圖標 */ .noquiet {display: inline-block;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -20px -762px;zoom: 0.2; }/* 快進圖標 */ .go {display: inline-block;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -515px -268px;zoom: 0.2; }/* 快退圖標 */ .back {display: inline-block;width: 220px;height: 217px;background-image: url(../img/icons.jpg);background-position: -268px -268px;zoom: 0.2; }.players {box-sizing: border-box;width: 770px;height: 110px;background-image: linear-gradient(#436881, #ea9e0d);padding: 13px 0;border-radius: 25px 10px 25px 10px;/* 左上角,右上角,右下角,左下角 */margin: 0 auto;}.container {width: 96%;height: 97%;background-color: white;margin: 0 auto;display: flex;justify-content: space-around; }.left {width: 23%;height: 100%;display: flex;justify-content: space-around;align-items: center; }.middle {width: 53%;height: 100%;align-items: center;display: flex;padding: 20px;box-sizing: border-box; }.right {width: 16%;height: 100%;display: flex;justify-content: space-around;align-items: center; }.verticle {width: 15%;align-items: center;height: 69%; }.music_detail {display: flex;}#currenttime {font-size: 13px;line-height: 35px;margin-left: 20px; }#totaltime {font-size: 13px;line-height: 35px; }.line {font-size: 13px;line-height: 35px; } .scroll{width: 500px;height: 13px;background-color: gray; } .bar{width: 0px;height: 13px;background-color: aquamarine;position: relative;pointer-events: none;/* pointer-events: none; 可以讓某個元素實現類似于海市蜃樓的效果,具體理解為,你可以看的到某個元素,但是你無法摸的著。 */cursor: move; } .dot{width: 5px;height: 13px;background-color: red;position: absolute;left: 0px;top: 0px; }總結
以上是生活随笔為你收集整理的JavaScript + Audio API自制简易音乐播放器(详细完整版、小白都能看懂)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十五、CSS 3新特性详解(三)——3D
- 下一篇: 二、Java 面向对象高级——Colle