效果
功能
- 歌曲切換
- 歌詞同步(並給樣式)
- 進度條拖動、點選
- 音量控制
- 監聽下一曲自動播放
技術解析
- json偽資料操作 ( 歌詞)
- 獲取audio屬性
- 建構函式,每首歌配置初始化
- 進度條操作,滑鼠事件
- 阿里雲圖示
網盤下載:連結:pan.baidu.com/s/1kV4hn9t 密碼:ezik
程式碼(靜態資源在網盤)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>音樂播放器</title>
<style type="text/css">
*{
padding: 0;
margin: 0
}
@font-face {font-family: 'iconfont';
src: url('font/iconfont.eot'); /* IE9*/
src: url('font/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('font/iconfont.woff') format('woff'), /* chrome、firefox */
url('font/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('font/iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
html,body{
height: 100%;
background: linear-gradient(top,#fb3737,#3323fd);
background: -moz-linear-gradient(top,#fb3737,#3323fd),-moz-linear-gradient(top,#fb3737,#3323fd);
background: -webkit-linear-gradient(top,#fb3737,#3323fd),-webkit-radial-gradient(ellipse,#fff,#fff);
}
.clear{}
.clear::after{
content: "";
display: block;
width: 100%;
height: 0;
clear: both;
}
.container{
position: absolute;
top:50%;
left: 50%;
margin-left: -400px;
margin-top: -300px;
width: 800px;
height: 600px;
/*border: 1px solid rgba(255,255,255,0.5);*/
box-shadow: 0 0 10px rgba(255,255,255,0.5);
background: linear-gradient(top,#fb4b4b,#3f3ffb);
background: -moz-linear-gradient(top,#fb4b4b,#3f3ffb);
background: -webkit-linear-gradient(top,#fb4b4b,#3f3ffb);
}
.music{
width: 50%;
height: 100%;
border-right: 1px solid rgba(255,255,255,0.5);
box-sizing: border-box;
float: left;
}
.photo{
width: 100%;
}
.photo_pic{
position: relative;
width: 250px;
height: 250px;
margin: 75px auto 0;
border-radius: 50%;
background: url(img/photo1.jpg);
box-shadow:0 0 2px #666, 0 0 10px #666;
}
.choose{
height:150px;
}
.choose_obj{
width: 50%;
float: left;
text-align: center;
color: #fff
}
.icon{
margin-top: 40px;
height: 50px;
font-size:50px;
line-height: 50px;
font-family: "iconfont";
cursor: pointer;
text-shadow: 2px 2px 0px #666;
}
.icon.yellow+span{
color: yellow;
}
.icon.pink+span{
color: #f7759f;
}
.choose_obj span{
display: block;
height: 30px;
line-height: 30px;
font-family: "微軟雅黑";
font-size: 14px;
}
.cd{
width: 10px;
height: 10px;
position: absolute;
top:50%;
left: 50%;
margin-top: -15px;
margin-left: -15px;
background: #666;
border: 10px solid #fff;
box-shadow: 0 0 1px #000;
border-radius: 50%;
}
.progress{
font-family: "iconfont"
}
.lyric{
width: 50%;
height: 100%;
float: right;
}
time{
font-size: 12px;
width: 49px;
text-align: center;
color: #fff;
height: 50px;
line-height: 50px;
float: left;
}
.progress_bar{
position: relative;
width: 300px;
height: 2px;
margin-top: 23px;
background-color: #fff;
float: left;
cursor: pointer;
}
.progress_cube{
position: absolute;
left: 0;
top: -5px;
width: 4px;
height: 4px;
background-color: #000;
border:5px solid #fff;
border-radius: 50%;
cursor: pointer;
}
.progress_obj{
line-height: 30px;
color: #fff;
}
.ctrl_btn{
width: 99px;
float: left;
}
.ctrl_btn .btn{
width: 33.3%;
float: left;
text-align: center;
cursor: pointer;
}
.play_btn{
font-size: 24px;
}
.ctrl_info{
width: 300px;
float: left;
}
.vol{
padding-left: 100px;
width: 100px;
height: 100%;
float: left;
}
.vol_bar{
position: relative;
width: 70px;
float: right;
height: 2px;
background-color: #fff;
margin-top: 13px;
}
.vol_cube{
position: absolute;
left: 0;
top: -4px;
width: 3px;
height: 3px;
background-color: #000;
border:4px solid #fff;
border-radius: 50%;
cursor: pointer;
}
.list{
width: 100px;
height: 100%;
float: right;
text-align: center;
}
.lyric_tit{
height: 50px;
line-height: 50px;
color: #fff;
text-align: center;
font-weight: 700;
margin-top: 30px;
}
.lyric_con{
position: relative;
line-height: 40px;
color: #fff;
font-size: 14px;
padding: 0px 50px ;
text-align: center;
height: 450px;
overflow: hidden;
margin-top: 20px;
}
#lyric_txt{
position: absolute;
left: 0;
top:0;
width: 100%;
height: 100%;
}
.lyric_con p.played{
color: yellow;
}
.lyric_con p.active{
color: yellow;
font-size: 20px;
font-weight: 700;
}
.audio{
display: none;
}
#list{
position: relative;
cursor: pointer;
}
#list_con{
position: absolute;
bottom: 30px;
right: 40px;
width: 150px;
height: 100px;
color: #666;
padding: 10px 0;
border-radius: 5px;
background: rgba(255,255,255,.8);
font-family: "微軟雅黑";
font-size: 14px;
cursor: pointer;
display: none;
}
</style>
</head>
<body>
<div class="container" id="container">
<div class="music">
<div class="photo">
<div class="photo_pic" id="photo_pic"><div class="cd"></div></div>
<div class="choose">
<div class="choose_obj choose_like" >
<div class="icon" id="icon1">
</div>
<span>喜歡</span>
</div>
<div class="choose_obj choose_share">
<div class="icon" id="icon2">
</div>
<span>收藏</span>
</div>
</div>
</div>
<div class="progress">
<div class="progress_obj clear">
<time>00:00</time>
<div class="progress_bar" id="progress_bar"><div class="progress_cube" id="progress_cube"></div></div>
<time>00:00</time>
</div>
<div class="progress_obj clear">
<div class="ctrl_btn">
<div id="prev_btn" class="prev_btn btn"></div>
<div id="play_btn" class="play_btn btn"></div>
<div id="next_btn" class="next_btn btn"></div>
</div>
<div class="ctrl_info">
<div class="vol"><div class="vol_bar" id="vol_bar"><div class="vol_cube" id="vol_cube"></div></div></div>
<div class="list" id="list"><div id="list_con"><p>fffffffff</p><p>fffffffff</p><p>fffffffff</p></div></div>
</div>
<audio src="song/王菲-笑忘書.mp3"></audio>
</div>
</div>
</div>
<div class="lyric">
<div class="lyric_tit" id="lyric_tit"></div>
<div class="lyric_con" id="lyric_con"><div id="lyric_txt"></div></div>
</div>
</div>
</body>
</html>
<script type="text/javascript">
//data
var lyric=[{'name':"笑忘書",'img':'img/photo1.jpg','audio_src':'song/王菲-笑忘書.mp3','content':"[00:00.00][00:01.00]笑忘書(國)[00:03.00]王菲[00:05.00][00:12.00]沒 沒有蠟燭 就不用勉強慶祝[00:17.00]沒 沒想到答案 就不用尋找題目[00:23.00]沒 沒有退路 問我也不要思路[00:29.00]沒 沒人去仰慕 那我就繼續忙碌[00:34.00]lalala 思前想後[00:37.00]差一點忘記了怎麼投訴[00:40.00]lalala 從此以後 不要犯同一個錯誤[00:46.00]將這樣的感觸 寫一封情書送給我自己[00:51.00]感動得要哭 很久沒哭[00:54.00]不失為天大的幸福 將這一份禮物[00:59.00]這一封情書 給自己祝福[01:02.00]可以不在乎 才能對別人在乎[01:20.00]有 一點幫助 就可以對誰傾訴[01:26.00]有 一個人保護 就不用自我保護[01:32.00]有 一點滿足 就準備如何結束[01:37.00]有 一點點領悟 就可以往後回顧01:43.00]lalala 思前想後[01:46.00]差一點忘記了怎麼投訴[01:49.00]lalala 從此以後 不要犯同一個錯誤[01:54.00]將這樣的感觸 寫一封情書送給我自己[01:59.00]感動得要哭 很久沒哭[02:03.00]不失為天大的幸福 將這一份禮物[02:08.00]這一封情書 給自己祝福[02:11.00]可以不在乎 才能對別人在乎[02:43.00]Lalalala....... Lalalala.......[02:55.00]從開始哭著忌妒 變成了笑著羨慕[03:00.00]時間是怎麼樣把握了我皮膚[03:03.00]只有我自己最清楚[03:06.00]將這樣的感觸 寫一封情書送給我自己[03:11.00]感動得要哭 很久沒哭[03:15.00]不失為天大的幸福 將這一份禮物[03:19.00]這一封情書 給自己祝福[03:22.00]可以不在乎 才能對別人在乎[03:28.00]讓我親手 將這樣的感觸[03:31.00]寫一封情書送給我自己[03:34.00]感動得要哭 很久沒哭[03:37.00]不失為天大的幸福[03:39.00]就好好將這一份禮物[03:42.00]這一封情書 給自己祝福[03:45.00]可以不在乎 才能對別人在乎 "
},{'name':"化身孤島的鯨",'img':'img/photo2.jpg','audio_src':'song/李逸朗-化身孤島的鯨.mp3','content':"[00:00.00] 化身孤島的鯨[00:03.00] 作詞:沃特艾文兒[00:06.00] 作曲:徐浩[00:09.00] 編曲:伍昊予[00:12.00] 演唱:李逸朗[00:15.00] Lrc By:吉時雨[00:18.00] QQ:132 7269 041[00:21.00] www.cnLyric.com [00:25.64] 我是隻化身孤島的藍鯨[00:28.94] 有著最巨大的身影[00:33.46] 魚蝦在身側穿行[00:37.23] 也有飛鳥在背上停[00:42.48] 我路過太多太美的奇景[00:45.85] 如同伊甸般的仙境[00:50.11] 而大海太平太靜[00:53.96] 多少故事無人傾聽[00:58.91] 我愛地中海的天晴[01:02.55] 愛西伯利亞的雪景[01:06.30] 愛萬丈高空的鷹[01:08.59] 愛肚皮下的藻荇[01:10.94] 我在盡心盡力地多情[01:14.20] 直到那一天[01:20.11] 你的衣衫破舊[01:22.19] 而歌聲卻溫柔[01:24.19] 陪我漫無目的地四處漂流[01:28.24] 我的背脊如荒丘[01:30.49] 而你卻微笑擺首[01:32.91] 把它當成整個宇宙[01:37.24] 你與太陽揮手[01:39.13] 也同海鷗問候[01:41.25] 陪我愛天愛地的四處風流[01:45.13] 只是遺憾你終究[01:47.33] 無法躺在我胸口[01:49.78] 欣賞夜空最遼闊的不朽[01:53.71] 把星子放入眸[02:03.33] 我是隻化身孤島的藍鯨[02:06.98] 有著最巨大的身影[02:10.96] 魚蝦在身側穿行[02:15.06] 也有飛鳥在背上停[02:20.18] 我有著太冷太清的天性[02:23.90] 對天上的她動過情[02:27.95] 而云朵太遠太輕[02:32.21] 輾轉之後各安天命[02:36.50] 我未入過繁華之境[02:40.35] 未聽過喧囂的聲音[02:44.05] 未見過太多生靈[02:46.24] 未有過滾燙心情[02:48.77] 所以也未覺大洋正中[02:52.58] 有多麼安靜[02:57.10] 你的衣衫破舊[02:59.02] 而歌聲卻溫柔[03:01.18] 陪我漫無目的四處漂流[03:05.32] 我的背脊如荒丘[03:07.34] 而你卻微笑擺首[03:10.16] 把它當成整個宇宙03:13.96] 你與太陽揮手[03:15.97] 也同海鷗問候[03:18.13] 陪我愛天愛地的四處風流[03:22.12] 只是遺憾你終究[03:24.20] 無法躺在我胸口[03:27.06] 欣賞夜空最遼闊的不朽[03:30.54] 把星子放入眸[03:34.73] 你的指尖輕柔[03:36.91] 撫摸過我所有[03:39.15] 風浪衝撞出的醜陋瘡口[03:43.03] 你眼中有春與秋[03:45.40] 勝過我見過愛過[03:47.78] 的一切山川與河流[03:51.98] 曾以為我肩頭[03:53.90] 是那麼的寬厚[03:55.92] 足夠撐起海底那座瓊樓[03:59.75] 而在你到來之後[04:02.09] 它顯得如此清瘦[04:04.55] 我想給你能奔跑的岸頭[04:08.20] 讓你如同王后"},{'name':"被馴服的象",'img':'img/photo3.jpg','audio_src':'song/蔡健雅-被馴服的象.mp3','content':"[00:00.00]被馴服的象[00:04.64]蔡健雅[00:09.74][00:22.46]到底要笑得多虛偽 才能夠融入這世界[00:28.13]每個人的臉上都像是貼了張一樣的假面[00:33.71]想不起我在做什麼 想不起我在想什麼[00:39.12]想不起靈魂深處 到底發生了什麼[00:43.95]迷霧 迷霧 在迷霧 我驚覺自己在原地踏步[00:49.03]到底是誰把我心矇住 不想再糊塗[00:54.63]迷路 迷路 迷了路 我就徹底被這團迷霧困住[00:59.92]誰能夠指引我一條路 帶我走上正途[01:07.94][01:16.94]裝不出融入的態度 空氣裡充斥著虛無[01:22.68]說什麼都掩飾不了我這局外人的侷促[01:28.21]想不通自己怎麼了 想不通世界怎麼了[01:33.61]想不通心靈深處 到底變成什麼了[01:38.30]迷霧 迷霧 在迷霧 我驚覺自己在原地踏步[01:43.54]到底是誰把我心矇住 不想再糊塗[01:49.24]迷路 迷路 迷了路 我就徹底被這團迷霧困住[01:54.46]誰能夠指引我一條路 帶我走上正途[02:00.34]掌聲 若需要掌聲 只要你願當被馴服的象[02:08.16]這舞臺你就可以上 榮耀 勝過被嘲笑[02:15.60]所以拋開自尊 咬緊牙根硬撐[02:21.92]迷霧 迷霧 在迷霧 我驚覺自己在原地踏步[02:27.11]到底是誰把我心矇住 不想再糊塗[02:32.89]迷路 迷路 迷了路 我就徹底被這團迷霧困住[02:38.08]誰能夠指引我一條路 帶我走上正途[02:44.13]迷路 迷路 迷了路 我就徹底被這團迷霧困住[02:48.94]誰能夠指引我一條路 帶我走上正途[02:59.51]"}]
window.onload=function()
{
var play_btn=document.getElementById("play_btn");
var prev_btn=document.getElementById("prev_btn");
var next_btn=document.getElementById("next_btn");
var audio=document.getElementsByTagName("audio")[0];
var initTime=document.getElementsByTagName("time")[0];
var time=document.getElementsByTagName("time")[1];
var progress_bar=document.getElementById("progress_bar");
var progress_cube=document.getElementById("progress_cube");
var vol_bar=document.getElementById("vol_bar");
var vol_cube=document.getElementById("vol_cube");
var lyric_con=document.getElementById("lyric_con");
var lyric_txt=document.getElementById("lyric_txt");
var photo_pic=document.getElementById("photo_pic");
var icon1=document.getElementById("icon1");
var icon2=document.getElementById("icon2");
var lyric_tit=document.getElementById("lyric_tit");
var list_con=document.getElementById("list_con");
var list_item=list_con.getElementsByTagName("p");
var songIndex=0;
var container=document.getElementById("container");
var obj;
function config()
{
this.play_mark=true;
this.duration=audio.duration;
this.play_btn="";
this.vol=audio.volume;
this.timer=null;
this.rotateSum=0;
this.icon1=icon1.innerHTML;
this.icon2=icon2.innerHTML;
this.icon1_co=icon1.style.color;
this.endplay_btn="";
this.endicon1=icon1.innerHTML;
this.endicon2="";
}
obj= new config();
//列表控制
var allSong="";
for(var song=0;song<lyric.length;song++)
{
allSong+="<p>"+lyric[song].name+"</p>"
}
list_con.innerHTML=allSong;
list_con.style.height=lyric.length*30+"px";
for(var listIndex=0;listIndex<list_item.length;listIndex++)
{
list_item[listIndex].index=listIndex;
list_item[listIndex].onclick=function(ev)
{
var ev=ev||window.event;
ev.stopPropagation();
songIndex=this.index;
change_music();
}
}
list_con.style.display="none";
list.onclick=function()
{
if(list_con.style.display=="none")
{
list_con.style.display="block";
}
else{
list_con.style.display="none";
}
}
//下一首
next_btn.onclick=function(){
songIndex++;
change_music();
}
prev_btn.onclick=function(){
songIndex--;
change_music();
}
function change_music()
{
clearInterval(obj.timer);
if(songIndex>=lyric.length)
{songIndex=0}
else if(songIndex<0)
{songIndex=lyric.length}
obj= new config();
iconinit();
audioInit();
playedTime();
lyric_ctrl();
}
//初始化總時長、音量等
function audioInit()
{
time.innerHTML=format(audio.duration);
audio.volume=0.5;
play_btn.innerHTML=obj.play_btn;
vol_cube.style.left=audio.volume*vol_bar.offsetWidth+"px";
lyric_tit.innerText=lyric[songIndex].name;
photo_pic.style.background="url("+lyric[songIndex].img+")";
audio.src=lyric[songIndex].audio_src;
progress_cube.style.left=0;
}
audioInit();
//播放時間
audio.addEventListener("timeupdate",function()
{
playedTime();
})
function playedTime(){
if(audio.currentTime==audio.duration)
{
next_btn.onclick();
play_btn.onclick();
}
var n=audio.currentTime/audio.duration;
progress_cube.style.left=n*progress_bar.offsetWidth+"px";
initTime.innerHTML=format(audio.currentTime);
var id_num=parseInt(audio.currentTime);
var lyric_p=document.getElementsByTagName("p");
for(var i=0;i<lyric_p.length;i++)
{
lyric_p[i].index=i;
}
if(document.getElementById("lyric"+id_num))
{
var obj=document.getElementById("lyric"+id_num);
for(var i=0;i<obj.index;i++)
{
lyric_p[i].className="played";
}
for(var j=obj.index;j<lyric_p.length;j++)
{
lyric_p[j].className="";
}
obj.className="yellow active";
lyric_txt.style.top=lyric_con.offsetHeight/2-obj.offsetTop+"px";
}
}
function format(time)
{
var time=parseInt(time);
var m=parseInt(time/60);
var s=parseInt(time%60);
m=zero(m);
s=zero(s);
function zero(num)
{
if(num<10)
{
num="0"+num;
}
return num;
}
return m+":"+s;
}
//拖拽進度條
progress_cube.onmousedown=function(ev)
{
var ev=ev||window.event;
var initX=ev.clientX-this.offsetLeft;
this.onmousemove=function(ev)
{
var ev=ev||window.event;
var x=ev.clientX-initX;
if(x<0){x=0}
if(x>progress_bar.offsetWidth-14){x=progress_bar.offsetWidth-14}
play_ctrl(x);
}
document.onmouseup=function()
{
document.onmousemove=null;
progress_cube.onmousemove=null;
}
}
function play_ctrl(x){
var timego=x/progress_bar.offsetWidth*audio.duration;
progress_cube.style.left=x+"px";
audio.currentTime=timego;
playedTime();
}
//點選進度條位置
progress_bar.onclick=function(ev)
{
var ev=ev||window.event;
var dis=ev.clientX-(container.offsetLeft+progress_bar.offsetLeft)-7;
progress_cube.style.left=dis+"px";
play_ctrl(dis);
}/**/
//拖動音量鍵
vol_cube.onmousedown=function(ev)
{
var ev=ev||window.event;
var initX=ev.clientX-vol_cube.offsetLeft;
this.onmousemove=function(ev)
{
var ev=ev||window.event;
var x=ev.clientX-initX;
if(x<0){x=0}
if(x>vol_bar.offsetWidth-11){x=vol_bar.offsetWidth-11}
var volresult=x/vol_bar.offsetWidth;
this.style.left=x+"px";
audio.volume=volresult;
}
document.onmouseup=function()
{
document.onmousemove=null;
vol_cube.onmousemove=null;
}
}
//點選播放
play_btn.onclick=function()
{
clearInterval(obj.timer);
if(obj.play_mark)
{
this.innerHTML=obj.endplay_btn;
audio.play();
obj.timer=setInterval(function()
{ obj.rotateSum=obj.rotateSum+1;
photo_pic.style.transform="rotate("+obj.rotateSum+"deg)";
},30)
}
else{
this.innerHTML=obj.play_btn;
audio.pause();
}
obj.play_mark=!obj.play_mark;
}
//歌詞處理
function lyric_ctrl()
{
var lyricObj=lyric[songIndex].content;
var temp=lyricObj.split("[");
var html="";
for(var i=0;i<temp.length;i++)
{
var arr=temp[i].split("]");
var text=(arr[1]);
var time=arr[0].split(",");
var temp2=time[0].split(".");
var ms=temp2[1];//毫秒
var temp3=temp2[0].split(":");
var s=temp3[1];//秒
var m=temp3[0];//分
var s_sum=parseInt(m*60)+parseInt(s);
if(text)
{
html+="<p id='lyric"+s_sum+"'>"+text+"</p>";
}
}
lyric_txt.innerHTML=html;
}
lyric_ctrl();
function iconinit(){
icon1.className="icon";
icon1.innerHTML=obj.icon1;
icon1.style.color="#fff";
icon2.className="icon";
icon2.style.color="#fff";
}
//喜歡 收藏
icon2.onclick=function()
{
if(this.innerHTML==obj.icon2)
{
this.innerHTML=obj.endicon2;
this.style.color="yellow";
this.className="icon yellow";
}
else{
this.innerHTML=obj.icon2;
this.style.color="#fff";
this.className="icon";
}
}
icon1.onclick=function()
{
if(this.style.color==obj.icon1_co)
{
this.innerHTML=obj.endicon1;
this.style.color="#f7759f";
this.className="icon pink";
}
else{
this.innerHTML=obj.icon1;
this.style.color=obj.icon1_co;
this.className="icon";
}
}
}
</script>
複製程式碼