1、最終效果

2、代碼思路

3、相關問題
? ? ? ? 1)出于功能需要,當使用audioObj.play()播放歌曲時,想通過duration屬性獲取歌曲的總時長,但總返回NaN。
? ? ? ? 這是因為剛開始播放時,歌曲的各項屬性信息還未加載到,所以需要在初始時為audioObj綁定事件監(jiān)聽,按照audio提供的方法,在loadedmetadata事件觸發(fā)時,音樂的各項參數(shù)都會加載完。
this.audioObj.onloadedmetadata=function(){
? ? ? ? _this.duration=_this.audioObj.duration;
? ? ? ? _this.play();
};
? ? ? ? 2)當音樂播放完成時,需要執(zhí)行一些操作。audio提供了兩種方法(ended方法和ended屬性),用哪種好呢?
? ? ? ? 自然是ended方法。起先因為要用計時器不斷獲取currentTime,我就想直接在計時器里順便監(jiān)測ended屬性,但是因為計時器是每秒執(zhí)行一次,所以可以明顯看到界面上的文字圖片都已經(jīng)切換到下一首了,而滑塊還會在進度條尾部停滯一下才跳回去。
? ? ? ? 3)還有一點值得注意,如果在進度條上綁定click事件以便調(diào)節(jié)音樂播放進度,需要在子元素上阻止冒泡(我的滑塊和時間戳都在進度條內(nèi))。
? ? ? ? 因為我是用vue編寫,所以比較簡單,只需給滑塊和時間戳添加@click.stop即可。
4、代碼優(yōu)化
? ? ? ? 1)在點擊“上一首”、“下一首”按鈕切歌時,需要確保序號不越界,起點最低被想到的是邏輯觀感比較好理解的if語句,但它的代碼觀感卻令人不爽。
? ? ? ? ① 如果是非循環(huán)播放,可使用Math.max和Math.min方法:
? ? ? ? this.index = Math.max(--this.index,0);
? ? ? ? this.index = Math.min(++this.index,this.total-1);
? ? ? ? ② 如果是循環(huán)播放,可使用取余法:
? ? ? ? this.index =(--this.index+this.total)%this.total;
? ? ? ? this.index = ++this.index%this.total;
? ? ? ? 2)在切換“播放/暫?!睍r,往往也最容易想到if判斷,但我覺得用三目代碼更優(yōu)雅一些。
? ? ? ? this.playing?this.pause():this.play();
Github下載鏈接:音樂播放器