使用jQuery仿製網易雲音樂移動端

預覽地址css

2018年05月01日21:37:28 完成了主頁的推薦音樂、熱歌榜、搜索和播放頁面。html


2018年4月20日15:18:13 這是一個項目筆記,用於記錄製做這個項目的點點滴滴。ajax


明確需求

原型圖
左一開始:主頁(推薦音樂)、熱歌榜、搜索、歌單和播放界面。

製做歷程

自定義一個工做流

我選擇了browser-sync,由於這個項目比較輕量(不須要引入不少的模塊),因此就直接用一個browoser-sync配合開發實時刷新就好了。項目完成之後再用打包工具build一個dist就行了~~正則表達式

旋轉的光盤

究竟是怎麼實現光盤旋轉?CSS動畫,利用keyframes:json

@keyframes circle {
	0% {
		transform: rotate(0deg);
	}
	100% {
		transform: rotate(360deg);
	}
}
.disc {
	animation:circle 20s infinite linear;
	/*選擇動畫,circle;時間;無限循環;線性變化*/
}
複製代碼
  1. 父容器page,上半層爲點唱機disc-container容器,下半層爲歌曲信息song-description。(把各個img素材添加進去。)
  2. 底部爲兩個按鈕鏈接,用一個div包裹links容器。(mock數據)
  3. page一個滿屏的高度,100vh。三個部分由上到下列式排布,用flax吧。而後根據判斷就給各個img設置寬高。

歌詞

  1. 先拿到歌詞請求。利用開發者工具裏面的network > filter > XHR拿到請求。複製一份,用來mock一份歌詞。保存爲json文件。
  2. 引入jQuery,發送一個ajax請求剛剛保存的lyric.json並把響應打出來(promise)
  3. 對lyr進行處理。(lyr指的是響應裏面的key爲lyric的值。lyr = object.lyric) 這是一個字符串,咱們經過以回車爲分隔符(‘\n’)組成一個新的數組打出來。 效果以下:
    效果圖
  4. 用到正則,匹配中括號裏面的時間和後面的歌詞內容。而後利用正則的api捕獲內容返回給array。注意,這裏用到map,是對array裏面的每一項string進行match。
  5. 把array的內容生成html的P標籤插入document中,屬性是時間。
  6. 高度爲顯示三行歌詞的高度。設置好字體大小,居中。
  7. 設置好active樣式,給歌詞lyric設定一個固定高度,給歌詞片斷p設置行高。
  8. 歌詞播放的時候調整lines(就是存放歌詞的div)的transform的樣式。

播放

  1. 拿到歌曲的src
  2. 把audio的各類api熟悉一下(播放、暫停、獲取當前時間、audio的事件)
  3. 當歌曲播放的時候,上方轉盤跟着旋轉。
  4. 添加播放按鈕(這裏我使用了圖片)。

暫停

  1. 點擊唱片,audio.pause(),同時移除表示playing的狀態class。

首頁

首頁的製做相對簡單些。api

  1. logo從官方的網頁剪下來,是一個svg(透明的,加個背景色就能看見了。)
  2. 完成其CSS樣式(這個就比較費時間和功夫了)
  3. 獲取幾首歌做爲樣本。能夠選擇放在七牛用來mock ajax請求。
  4. mock一個song.json,而後把html上寫死了的節點刪除。根據返回的json拼接成html並插入到dom上。
  5. 首頁載入之後,在相應數據到來以前,應該顯示一個loading的動畫表示正在加載數據;當數據到來之後渲染頁面元素,並移除loading動畫,目的就是爲了提高用戶體驗。(能夠用gif,也能夠旋轉一個svg圖標。)
  6. 發送ajax請求,根據響應對跳轉連接的地址進行拼接,同時對歌曲信息進行拼接。(ES6模板字符串)
    代碼截圖
  7. 拼接完畢之後就渲染到html上,並把載入動畫移除。
    效果圖
  8. 點擊之後,就會跳轉到./song.html,同時附帶上歌曲的id。在song.js上,根據location.search得到歌曲的id。(須要用正則匹配)
location.search.match(/\bid=([^&]*)/)[1]
複製代碼

熱歌榜

其實熱歌榜的難度不大,裏面的歌曲載入能夠服用前面首頁的loadmusic,因此就略過吧。數組

搜索

  1. 須要對api進行修改,把搜索建議的目標地址改一下,改成suggest/keyword 若是響應裏面的code===200,說明成功了。
    效果
  2. 搜索提示可點擊、熱搜tag可點擊。

歌詞滾動

  1. 首先要獲取當前歌曲的進度時間:audio.currentTime獲得的是當前播放進度的秒數(注意,須要設置定時每隔500毫秒獲取一次)
  2. 轉換爲正常的時間顯示01:25,實質是把分鐘數和秒數拼接一塊兒,須要解決的就是數字的取整,判斷是否須要加0
setInterval(()=>{
	let  nowScends  =  audio.currentTime;
	let  minutes  =  ~~(nowScends/60)
	let  scends  =  ~~(nowScends%60)
	let  currentTime  = `${padTime(minutes)}:${padTime(scends)}`;
 },300)
function padTime(number) {
      return  number>10?number+'':'0'+number
    }
複製代碼
  1. 實現歌詞滾動的代碼:
let  $lrcArray  =  $('.lyric .lines>p'); //這裏取的是每一段歌詞的集合。
let  lrcLength  =  $lrcArray.length;
for(let  i=0;  i<lrcLength;  i++){
	let  $whitchLines  =  $lrcArray.eq(i);	//指應當顯示的歌詞行
	let  $nextLines  =  $lrcArray.eq(i+1);	//指接下來要顯示的歌詞行
	
	//當沒有下一段歌詞的時候,意味歌曲播放到最後,return。
	if($nextLines.length  ===  0){            
		return;
	}else if($whitchLines.attr('data-time')  <  currentTime  &&  $nextLines.attr('data-time')>currentTime){
		//遍歷全部歌詞,針對其屬性`data-time`與當前的`currentTime`進行比較,若是當前時間比`i`的`data-time`大,比`i+1`的小,說明此時歌詞應該是在`i`與`i+1`之間,應該顯示$whitchLines的內容。
		$whitchLines.addClass('active').siblings().removeClass('active')
		let  gap  =  $whitchLines.offset().top  -  $('.lines').offset().top  ;
		log('gap ='+  gap)
		//由於歌詞顯示區域的高度是顯示五行歌詞,那麼中間的高度就是總高度的五分之三
		let  middle  =  $('.lyric').height()  /  5  *  2
		$('.lines').css('transform',`translateY(-${gap-middle}px)`)
	}
}
複製代碼

難點記錄與解決歷程

1. `處理歌詞data,須要會用正則來對字符串進行分割。`
解決:能夠利用在線正則網站好好設計一遍你的正則表達式。

2. `對播放動畫進行設計,實現播放暫停的時候唱片旋轉角度不會歸零。`
解決:使用 `animation-play-state: paused `
3. `mock數據會很繁瑣。`
解決:七牛存儲/自建api

4. `搜索框提示`和`搜索顯示內容的節流`

5. `歌詞滾動`
解決:要想好好歌詞顯示的邏輯:
	- 肯定歌曲時間戳(`audio.currentTime`)
	- 根據時間戳匹配歌詞(遍歷歌詞節點,根據歌詞節點的`data-time`屬性與時間戳進行比較,當時間戳位於兩行歌詞的`data-time`之間,高亮上一條歌詞)
	- 滾動歌詞(`transform:translateY`)
複製代碼

待更新promise

相關文章
相關標籤/搜索