H5增加了很多的標籤,面試的時候,如果面試官問你H5都有哪些新標籤,你回答header、footer、nav。
這麼回答幾乎是無效的,因爲這些標籤在H5裏面的角色,相當於雞骨頭、魚刺、蘑菇腿——全是雞肋,至少你得答出來audio、video、canvas,這些纔是H5的核心功能,本文我們就重點說一下audio。
audio廣泛的應用於各種項目中,遊戲背景、各種播放器,可以說有聲音的地方就有audio,當然因爲各種限制和坑,很容易讓前端人員陷入尷尬,比如在iphone下audio 是不允許autoplay的,如果前端人員不知道這個坑,產品經理又拿微信做對比,那這個鍋前端就背定了。
所以本文通過對audio的核心知識的講解,讓用戶一來不背鍋,二來不加班。
第一步非常簡單你就把audio當成圖片使用,搞出個src,剩下ul是歌曲列表,然後是一堆功能按鈕,不再贅述。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>網易雲音樂</title>
</head>
<body>
<audio src="mp3/千千闕歌.mp3" id="audio" controls></audio>
<h3>點擊開始播放</h3>
<ul>
<li>
<a href="javascript:;">千千闕歌</a>
</li>
<li>
<a href="javascript:;">時間都去哪兒了</a>
</li>
<li>
<a href="javascript:;">小蘋果</a>
</li>
<li>
<a href="javascript:;">夜的鋼琴曲</a>
</li>
<li>
<a href="javascript:;">雨的印記</a>
</li>
</ul>
<div>
<div></div>
<div></div>
</div>
<div>
<input type="button" value="上一曲" id="prev">
<input type="button" value="播放" id="play">
<input type="button" value="下一曲" id="next">
<input type="button" value="單曲循環" id="singleLoop">
<input type="button" value="順序播放" id="queue">
<input type="button" value="隨機播放" id="randomQueue">
<input type="button" value="循環播放" id="menuloop">
</div>
</body>
</html>
這樣的播放控制條很醜,產品經理會很不滿意,當然了,如果產品經理說真好看,那你就換公司吧,我們需要隱藏控制條,然後自己用各種按鈕和標籤模擬一個。
第一個功能,播放暫停,
//播放
oPlay.onclick = function () {
if (oA.paused) {
this.value = '暫停'
oA.play();
} else {
this.value = '播放'
oA.pause();
}
};
然後整下一曲,
var arrSong = [
'千千闕歌',
'時間都去哪兒了',
'小蘋果',
'夜的鋼琴曲',
'雨的印記'
];
//下一曲
function play() {
for (var i = 0; i < aA.length; i++) {
aA[i].className = '';
}
aA[iNow].className = 'on';
oA.src = 'mp3/' + arrSong[iNow] + '.mp3';
oA.play();
}
//下一曲
oNext.onclick = function () {
iNow++;
if (iNow >= arrSong.length) {
iNow = 0;
}
oPlay.value = '暫停';
play();
};
這裏大家要注意,我使用的是數組的形式,因爲數組要比單獨處理某一個音樂更方便。下面是單曲循環,
//單曲循環
oSingleLoop.onclick = function () {
oA.loop = !oA.loop;
};
這裏涉及到一個坑,很多人會覺得我直接在mp3播放onend事件裏面在播放一次原來的音樂不就可以了嗎?
確實可以問題是麻煩,因爲自身就有了loop屬性,但是隨機播放或者整個列表重複就沒有屬性了,這裏就要使用switch case判斷。
//順序播放
oQueue.onclick = function () {
oA.playState = 2;
};
//隨機播放
oRandomQueue.onclick = function () {
oA.playState = 3;
};
//列表循環
oMenuloop.onclick = function () {
oA.playState = 4;
};
//播放完畢,單曲循環
oA.onended = function () {
switch (oA.playState) {
case 2:
iNow++;
if (iNow < arrSong.length) {
play();
}
break;
//隨機
case 3:
iNow = rnd(0, arrSong.length);
play();
break;
//列表循環
case 4:
iNow++;
if (iNow > arrSong.length) iNow = 0;
play();
break;
}
};
這裏算是一個功能實現技巧,通過開關,上面說這些都很簡單,我們實現一個看起來複雜其實非常簡單的的功能,進度條,其實進度就是當前時間總時間,這裏要用一個timeupdate事件,因爲播放的過程中時間是不斷變化的。
oA.addEventListener('timeupdate', activeProgressBar, false);
function activeProgressBar() {
var percentNum = Math.floor((oA.currentTime / oA.duration) * 10000) / 100 + '%';
progress.style.width = percentNum;
progressBtn.style.left = percentNum;
}
這裏,給大家順便留一個作業,如何實現進度條拖拽改變,播放進度呢?
var percentNum = (e.targetTouches[0].pageX - progressBar.getBoundingClientRect().left) / progressBar.getBoundingClientRect().width;
提示大家兩個坑,第一個坑是mp3加載,建議使用preloadjs而不是preload屬性。
第二給大家一個事件,
audio.addEventListener('loadedmetadata', function() {
console.log("Playing " + audio.src + ", for: " + audio.duration + "seconds.");
audio.play();
});
這個事件用在頁面加載完,但是mp3如果沒有加載到位會出現獲取音樂時長NaN問題,用這個就OK了。
最後給大家留一個作業,
實現https://music.163.com/#/my/m/music/playlist網易雲音樂App的上一曲、下一曲、單曲、列表循環、順序播放,以及播放進度控制CD封面旋轉功能。
·END·