jQuery仿QQ音乐播放器

本文通过Html+CSS+jQuery开发仿QQ版的音乐播放器,是前端技术的综合应用,所用素材来源于网络,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点

在本例中用到的知识点如下,按jQuery和CSS进行区分:

jQuery 是一个 JavaScript 库, 极大地简化了 JavaScript 编程,常见知识点如下:

  1. 通过标签获取jQuery对象:var $audio =$("audio");
  2. 通过选择符获取jQuery对象并设置文本内容:$(".music_progrss_time").text(timeStr);
  3. 通过选择符,标签名获取对象并获取第i个子元素:$(".song_lyric ul li").eq(index);
  4. 通过ajax异步获取数据并刷新页面:$.ajax({});
  5. 通过类选择符获取元素并进行隐藏或显示:$(this).find(".list_menu").stop().fadeIn(100);
  6. 通过委托动态设置单击事件,主要针对动态生成元素:$(".content_list").delegate(".list_check", "click", function() {});
  7. 通过addClass添加类,removeClass删除类,toggleClass切换类,hasClass是否包含类
  8. 获取与对象同级的兄弟节点:$musicList.siblings();
  9. 触发相关事件:$(".music_next").trigger("click");

CSS通过使用 CSS 我们可以大大提升网页开发的工作效率!本例使用知识点如下:

  1. 设置距离左边的距离:margin-left: 20px; 设置距离右边的距离:margin-right: 20px;
  2. 设置透明度:opacity: 0.6; 值[0,1]从透明到全不透明
  3. 设置背景图片:background: url(../img/player_logo.png) no-repeat 0 0;设置背景颜色和透明度:background: rgba(255,255,255,0.5);
  4. 设置li的样式:list-style: none;
  5. 设置显示样式为行内块:display: inline-block;
  6. 设置圆角:border-radius: 5px;
  7. 设置相对位置:position: relative;
  8. 背景图片的起始坐标:background-position: 0 -75px;

示例效果图及结构划分

本例的示例效果图及结构划分如下所示:

jQuery仿QQ音乐播放器_第1张图片

 

 

 Html核心代码

Header部分代码:主要用于显示logo和登录显示,如下所示:

1 <div class="header">
2     <h1 class="logo">
3         <a href="#">a> --by Alan.hsiang
4     h1>
5     <ul class="register">
6         <li>登录li>
7         <li>设置li>
8     ul>
9 div>

中间区域部分:主要包括坐边的列表和右边的歌曲相关,如下所示:

 1 <div class="content">
 2     <div class="content_in">
 3         <div class="content_left">
 4             <div class="content_toolbar">
 5                 <span><i>i>收藏span>
 6                 <span><i>i>添加到span>
 7                 <span><i>i>下载span>
 8                 <span><i>i>删除span>
 9                 <span><i>i>清空列表span>
10             div>
11             <div class="content_list">
12                 <ul>
13                     <li class="list_title">
14                         <div class="list_check"><i>i>div>
15                         <div class="list_number">div>
16                         <div class="list_name">歌曲div>
17                         <div class="list_singer">歌手div>
18                         <div class="list_time">时长div>
19                     li>
20                 ul>
21             div>
22         div>
23         <div class="content_right">
24             <div class="song_info">
25                 <a href="javascript:;" class="song_info_pic">
26                     <img src="" alt="" />
27                 a>
28                 <div class="song_info_name">歌曲名称:<a href="javascript:;" class="">a>div>
30                 <div class="song_info_singer">歌手名:<a href="javascript:;" class="">a>div>
32                 <div class="song_info_album">专辑名称:<a href="javascript:;" class="">a>div>
34             div>
35             <div class="song_lyric"><ul>ul>div>
37         div>
38     div>
39 div>
40                 

底部区域代码,主要用于播放相关内容,如下所示:

 1 <div class="footer">
 2     <div class="footer_in">
 3         <a href="javascript:;" class="music_pre" title="上一首">a>
 4         <a href="javascript:;" class="music_play" title="播放">a>
 5         <a href="javascript:;" class="music_next" title="下一首">a>
 6         <div class="music_progress_info">
 7             <div class="music_progress_top">
 8                 <span class="music_progrss_name">span>
 9                 <span class="music_progrss_time">span>
10             div>
11             <div class="music_progress_bar">
12                 <div class="music_progress_line">
13                     <div class="music_progress_dot">div>
16                 div>
17             div>
18         div>
19         <a href="javascript:;" class="music_mode" title="播放模式">a>
20         <a href="javascript:;" class="music_fav" title="收藏">a>
21         <a href="javascript:;" class="music_down" title="下载">a>
22         <a href="javascript:;" class="music_comment" title="评论">a>
23         <a href="javascript:;" class="music_only" title="纯净模式">a>
24         <div class="music_voice">
25             <a href="javascript:;" class="music_voice_info" title="声音">a>
26             <div class="music_voice_bar">
27                 <div class="music_voice_line">
28                     <div class="music_voice_dot">div>
29                 div>
30             div>
31         div>
32     div>
33 div>
34         

jQuery功能性核心代码

在本示例中,从功能上区分,主要分为播放模块,进度条模块,歌词模块,各个模块相互独立,所以进行了适当的封装。

播放模块【Play】主要包括歌曲的初始化,播放与暂停,上一首,下一首,播放同步,跳转等功能,核心代码如下:

 1 (function(window){
 2     function Player($audio){
 3         return new Player.prototype.init($audio);
 4     }
 5     Player.prototype={
 6         constructor :Player,
 7         musicList:[],
 8         currIndex:-1,
 9         $audio:null,
10         audio:null,
11         init:function($audio){
12             this.$audio=$audio;//jQuey包装对象
13             this.audio=$audio.get(0);//原生audio对象
14         },
15         play:function(index,music){
16             console.log(index,music);
17             console.log(this.$audio);
18             if(this.currIndex==index){
19                 //同一首音乐,则是暂停,播放之间切换
20                 
21                 if(this.audio.paused){
22                     this.audio.play();
23                 }else{
24                     this.audio.pause();
25                 }
26             }else{
27                 //不是同一首,重新播放
28                 this.$audio.attr('src',music.link_url);
29                 this.audio.play();
30                 this.currIndex=index;
31             }
32         },
33         preIndex:function(){
34             var index=this.currIndex-1;
35             if(index<0){
36                 index=this.musicList.length-1;
37             }
38             return index;
39         },
40         nextIndex:function(){
41             var index=this.currIndex+1;
42             if(index>this.musicList.length-1){
43                 index=0;
44             }
45             return index;
46         },
47         del:function(index){
48             this.musicList.splice(index,1);
49             if(index<this.currIndex){
50                 this.currIndex=this.currIndex-1;
51             }
52         },
53         musicTimeUpdate:function(callBack){
54             //需要一个回调函数作为参数
55             var that=this;
56             //监听audio播放事件
57             this.$audio.on("timeupdate",function(){
58                 var duration=that.audio.duration;
59                 var currentTime=that.audio.currentTime;
60                 var timeStr=that.formatTime(currentTime,duration);
61                 //参数是一个回调函数
62                 callBack(duration,currentTime,timeStr);
63             });
64         },
65         //定义一个格式化时间的方法
66         formatTime:function (currentTime,duration){
67             //总时长
68             var endMin=parseInt(duration/60);
69             var endSec=parseInt(duration%60);
70             endMin=endMin<10?"0"+endMin:endMin;
71             endSec=endSec<10?"0"+endSec:endSec;
72             //当前时长
73             var curMin=parseInt(currentTime/60);
74             var curSec=parseInt(currentTime%60);
75             curMin=curMin<10?"0"+curMin:curMin;
76             curSec=curSec<10?"0"+curSec:curSec;
77             return curMin+":"+curSec+" / "+endMin+":"+endSec;
78         },
79         musicSeekTo:function(value){
80             var that=this;
81             var duration=that.audio.duration;
82             if(isNaN(duration))return;
83             if(isNaN(value))return;
84             that.audio.currentTime=duration*value ;
85         },
86         musicVoiceSeekTo:function(value){
87             if(isNaN(value))return;
88             if(value<=0 || value>=1) return;
89             this.audio.volume=value;
90         }
91     };
92     Player.prototype.init.prototype=Player.prototype;
93     window.Player=Player;
94 })(window);
View Code

歌词模块【lyric】,主要包括歌词的加载,解析,同步等功能,核心代码如下:

 1 (function(window){
 2     function Lyric(path){
 3         return new Lyric.prototype.init(path);
 4     }
 5     Lyric.prototype={
 6         constructor :Lyric,
 7         times:[],
 8         lyrics:[],
 9         index:-1,
10         init:function(path){
11             this.path=path;
12         },
13         loadLyric:function(callBack){
14             var that=this;
15             $.ajax({
16                 type: "get",
17                 dataType:"text",
18                 contentType: "application/text; charset=utf-8",
19                 url: that.path,
20                 success: function(data) {
21                     //console.log(data);
22                     that.parseLyric(data);
23                     callBack();
24                 },
25                 error: function(e) {
26                     console.log(e);
27                 }
28             });
29         },
30         parseLyric:function(data){
31             var that=this;
32             //初始化歌词和时间
33             that.times=[];
34             that.lyrics=[];
35             that.index=-1;
36             //
37             var array=data.split("\n");
38             //console.log(array);
39             var timeReg=/\[(\d*:\d*\.\d*)\]/;
40             $.each(array, function(index,ele) {
41                 //console.log(ele);
42                 //
43                 var lyc=ele.split("]")[1];
44                 if(lyc==null || lyc.length==1){
45                     return true;//排除空字符串
46                 }
47                 that.lyrics.push(lyc);
48                 
49                 var res=timeReg.exec(ele);
50                 //console.log(res);
51                 if(res==null){
52                     return true; //排除空时间
53                 }
54                 var timeStr=res[1];
55                 var res2=timeStr.split(":");
56                 var min=parseInt(res2[0]) *60;
57                 var sec=parseFloat(res2[1]) ;
58                 var res3=parseFloat( Number(min+sec).toFixed(2));
59                 //console.log(res3);
60                 that.times.push(res3);
61             });
62             console.log(that.times.length +"  , "+ that.lyrics.length);
63         },
64         currentLyric:function(currentTime){
65             //console.log(currentTime);
66             if(currentTime>this.times[0]){
67                 this.index++;
68                 this.times.shift();//删除第一个元素,并返回剩余的数组
69             }
70             return this.index;
71         }
72     };
73     Lyric.prototype.init.prototype=Lyric.prototype;
74     window.Lyric=Lyric;
75 })(window);
View Code

进度条模块【Progress】主要包括:进度条的初始化,单击,拖动,回调等功能,核心代码如下:

 1 (function(window){
 2     function Progress($progressBar,$progressLine,$progressDot){
 3         return new Progress.prototype.init($progressBar,$progressLine,$progressDot);
 4     }
 5     Progress.prototype={
 6         constructor :Progress,
 7         isMove:false,
 8         init:function($progressBar,$progressLine,$progressDot){
 9             this.$progressBar=$progressBar;
10             this.$progressLine=$progressLine;
11             this.$progressDot=$progressDot;
12         },
13         progressClick:function(callBack){
14             //console.log(this.$progressBar);
15             var that=this;//此时的this表示Progress
16             this.$progressBar.click(function(event){
17                 //此时的this表示progrssBar点击的对象
18                 var normalLeft = $(this).offset().left;//控件默认距左边的位置
19                 var eventLeft = event.pageX;//当前鼠标点击的距左边的位置
20                 that.$progressLine.css("width",eventLeft-normalLeft);
21                 that.$progressDot.css("left",eventLeft-normalLeft);
22                 //计算进度条的比例
23                 var value=(eventLeft-normalLeft)/$(this).width();
24                 callBack(value);
25             });
26         },
27         progressMove:function(callBack){
28             var that=this;//此时的this表示Progress
29             var normalLeft =-1;
30             var eventLeft=-1;
31             var barWidth=this.$progressBar.width();
32             this.$progressBar.mousedown(function(){
33                 that.isMove=true;
34                 normalLeft = $(this).offset().left;//控件默认距左边的位置
35                 
36                 $(document).mousemove(function(){
37                     //此时的this表示progrssBar点击的对象
38                     eventLeft = event.pageX;//当前鼠标点击的距左边的位置
39                     var v=eventLeft-normalLeft;
40                     if(v>=0 && v<=barWidth){
41                         //判断值的有效范围再赋值
42                         that.$progressLine.css("width",eventLeft-normalLeft);
43                         that.$progressDot.css("left",eventLeft-normalLeft);
44                     }
45                 });
46             });
47             $(document).mouseup(function(){
48                 $(document).off("mousemove");
49                 that.isMove=false;
50                 //计算进度条的比例
51                 var value=(eventLeft-normalLeft)/that.$progressBar.width();
52                 //鼠标抬起时触发,防止音乐断断续续
53                 callBack(value);
54             });
55         },
56         setProgress:function(value){
57             if(this.isMove)return;
58             if(value<0 || value>100){
59                 return;
60             }
61             this.$progressLine.css("width",value+"%");
62             this.$progressDot.css("left",value+"%");
63         }
64     };
65     Progress.prototype.init.prototype=Progress.prototype;
66     window.Progress=Progress;
67 })(window);
View Code

加载流程,包括初始化歌曲列表,歌词信息,注册事件,初始化进度条等功能,本例中的歌曲列表和歌词信息,均是通过ajax从本地文件中获取,核心代码如下:

  1 $(function() {
  2     var $audio =$("audio");
  3     var player=new Player($audio);
  4     var progress=null;
  5     var voiceProgress=null;
  6     var lyric=null;
  7     //1.加载音乐
  8     getPlayerList();
  9     //2.注册事件
 10     initEvent();
 11     //3.初始化进度条,包括声音
 12     initProgress();
 13     
 14     //音乐播放同步
 15     player.musicTimeUpdate(function(duration,currentTime,timeStr){
 16         //同步时间
 17         $(".music_progrss_time").text(timeStr);
 18         //同步进度条
 19         var value=currentTime/duration *100;
 20         progress.setProgress(value);
 21         //实现歌词同步
 22         var oldIndex=lyric.index;
 23         var index=lyric.currentLyric(currentTime);
 24         if(oldIndex==index)return;
 25         var item=$(".song_lyric ul li").eq(index);
 26         item.addClass("cur");
 27         item.siblings().removeClass("cur");
 28         if(index<0) return;
 29         $(".song_lyric ul").css({
 30             marginTop:(-index+2)*40
 31         });
 32     })
 33     
 34     //获取列表函数
 35     function getPlayerList() {
 36         $.ajax({
 37             type: "get",
 38             url: "music_list.json",
 39             success: function(data) {
 40                 //player.musicList=data;
 41                 //console.log(data);
 42                 var musicList = $(".content_list ul");
 43                 $.each(data, function(index, ele) {
 44                     var item = createMusicItem(index, ele);
 45                     musicList.append(item);
 46                 });
 47                 //默认初始化第一首歌曲信息
 48                 initMusicInfo(data[0]);
 49                 
 50                 //初始化歌词信息
 51                 initMusicLyric(data[0]);
 52             },
 53             error: function(e) {
 54                 console.log(e);
 55             }
 56         });
 57     }
 58     //定义一个方法,创建一条音乐
 59     function createMusicItem(index, music) {
 60         var $item = $("
  • \n" + 61 "
    \n" + 62 "\n" + 63 "
    \n" + 64 "
    \n" + 65 (index + 1) + 66 "
    \n" + 67 "
    \n" + 68 music.name + 69 "
    \n" + 70 "\n" + 71 "\n" + 72 "\n" + 73 "\n" + 74 "
    \n" + 75 "
    \n" + 76 "
    \n" + 77 music.singer + 78 "
    \n" + 79 "
    \n" + 80 "\n" + 81 music.time + 82 "\n" + 83 "\n" + 84 "
    \n" + 85 "
  • "); 86 $item.get(0).index=index; 87 $item.get(0).music=music; 88 return $item; 89 } 90 91 //初始化音乐信息 92 function initMusicInfo(music){ 93 //获取元素 94 var $musicImg=$(".song_info_pic img"); 95 var $musicName=$(".song_info_name a"); 96 var $musicSinger=$(".song_info_singer a"); 97 var $musicAlbum=$(".song_info_album a"); 98 var $musicTopName=$(".music_progrss_name"); 99 var $musicTopTime=$(".music_progrss_time"); 100 var $musicBg=$(".mask_bg"); 101 //赋值 102 $musicImg.attr("src",music.cover); 103 $musicName.text(music.name); 104 $musicSinger.text(music.singer); 105 $musicAlbum.text(music.album); 106 $musicTopName.text(music.name+" / "+ music.singer); 107 $musicTopTime.text("00:00 / "+music.time); 108 $musicBg.css("background","url('"+music.cover+"') no-repeat 0 0;"); 109 110 } 111 112 //初始化歌词信息 113 function initMusicLyric(music){ 114 lyric=new Lyric(music.link_lrc); 115 var lyricContainer=$(".song_lyric ul"); 116 //清空信息 117 lyricContainer.html(""); 118 //加载歌词 119 lyric.loadLyric(function(){ 120 //加载完成后处理函数 121 $.each(lyric.lyrics,function(index,ele){ 122 var item=$("
  • "+ele+"
  • "); 123 lyricContainer.append(item); 124 }); 125 }); 126 } 127 //注册事件 128 function initEvent() { 129 //监听歌曲的移入移出事件 130 //通过委托动态监听事件 131 $(".content_list").delegate(".list_music", "mouseover", function() { 132 //移入事件:1.显示子菜单 2. 隐藏时长 ,显示删除按钮 133 $(this).find(".list_menu").stop().fadeIn(100); 134 $(this).find(".list_time a").stop().fadeIn(100); 135 $(this).find(".list_time span").stop().fadeOut(100); 136 // 137 $(this).find(".list_name").addClass("list_music_hover"); 138 }); 139 $(".content_list").delegate(".list_music", "mouseleave", function() { 140 //移出事件:1.隐藏子菜单 2. 显示时长 ,隐藏删除按钮 141 $(this).find(".list_menu").stop().fadeOut(100); 142 $(this).find(".list_time a").stop().fadeOut(100); 143 $(this).find(".list_time span").stop().fadeIn(100); 144 $(this).find(".list_name").removeClass("list_music_hover"); 145 }); 146 147 //以下绑定事件只针对静态语句 148 // $(".list_music").hover(function(){ 149 // //移入事件:1.显示子菜单 2. 隐藏时长 ,显示删除按钮 150 // $(this).find(".list_menu").stop().fadeIn(100); 151 // $(this).find(".list_time a").stop().fadeIn(100); 152 // $(this).find(".list_time span").stop().fadeOut(100); 153 // },function(){ 154 // //移出事件:1.隐藏子菜单 2. 显示时长 ,隐藏删除按钮 155 // $(this).find(".list_menu").stop().fadeOut(100); 156 // $(this).find(".list_time a").stop().fadeOut(100); 157 // $(this).find(".list_time span").stop().fadeIn(100); 158 // }); 159 160 $(".content_list").delegate(".list_check", "click", function() { 161 $(this).toggleClass("list_checked"); 162 var musicList = $(this).parents(".list_music"); 163 if($(this).hasClass("list_checked")) { 164 musicList.find("div").css("color", "#fff"); 165 musicList.siblings().find("div").css("color", "rgba(255,255,255,0.5)"); 166 } else { 167 musicList.find("div").css("color", "rgba(255,255,255,0.5)"); 168 } 169 }); 170 // //监听复选框的点击事件 171 // $(".list_check").click(function(){ 172 // $(this).toggleClass("list_checked"); 173 // }); 174 175 //监听点击播放事件 176 $(".content_list").delegate(".list_menu_play", "click", function() { 177 //切换播放图标 178 $(this).toggleClass("list_menu_play2"); 179 //还原其他项的图标 180 var $musicList = $(this).parents(".list_music"); 181 182 // console.log($musicList.get(0).index); 183 // console.log($musicList.get(0).music); 184 185 $musicList.siblings().find(".list_menu_play").removeClass("list_menu_play2"); 186 //底部图标同步 187 if($(this).hasClass("list_menu_play2")) { 188 $(".music_play").addClass("music_pause"); 189 $musicList.find("div").css("color", "#fff"); 190 $musicList.siblings().find("div").css("color", "rgba(255,255,255,0.5)"); 191 } else { 192 $(".music_play").removeClass("music_pause"); 193 $musicList.find("div").css("color", "rgba(255,255,255,0.5)"); 194 } 195 $musicList.find(".list_number").toggleClass("list_number_play"); 196 $musicList.siblings().find(".list_number").removeClass("list_number_play"); 197 //播放 198 player.play($musicList.get(0).index,$musicList.get(0).music); 199 // 200 initMusicInfo($musicList.get(0).music); 201 //同步歌词 202 initMusicLyric($musicList.get(0).music); 203 }); 204 205 //监听删除事件 206 $(".content_list").delegate(".list_menu_del", "click", function() { 207 var $item=$(this).parents(".list_music"); 208 $item.remove(); 209 player.del($item.get(0).index); 210 if($item.get(0).index==player.currIndex){ 211 //如果删除的是当前播放的歌曲,则自动播放下一首 212 $(".music_next").trigger("click"); 213 } 214 //修改序号 215 $(".list_music").each(function(index,ele){ 216 ele.index=index; 217 $(ele).find(".list_number").text(index+1); 218 }); 219 }); 220 //监听底部按钮 221 //播放 222 $(".music_play").click(function(){ 223 //判断是否有播放过音乐 224 if(player.currIndex==-1){ 225 //表示没有播放过 226 $(".list_music").eq(0).find(".list_menu_play").trigger("click"); 227 228 }else{ 229 //表示之前有播放过 230 $(".list_music").eq(player.currIndex).find(".list_menu_play").trigger("click"); 231 } 232 }); 233 //前一首 234 $(".music_pre").click(function(){ 235 $(".list_music").eq(player.preIndex()).find(".list_menu_play").trigger("click"); 236 }); 237 //下一首 238 $(".music_next").click(function(){ 239 $(".list_music").eq(player.nextIndex()).find(".list_menu_play").trigger("click"); 240 }); 241 //声音事件 242 $(".music_voice_info").click(function(){ 243 //图标切换 244 $(this).toggleClass("music_voice_info2"); 245 if($(this).hasClass("music_voice_info2")){ 246 //无声音 247 player.musicVoiceSeekTo(0); 248 }else{ 249 //有声音 250 player.musicVoiceSeekTo(1); 251 } 252 }); 253 } 254 //初始化进度条 255 function initProgress(){ 256 //进度条 257 var $progressBar=$(".music_progress_bar"); 258 var $progressLine=$(".music_progress_line"); 259 var $progressDot=$(".music_progress_dot"); 260 progress=new Progress($progressBar,$progressLine,$progressDot); 261 progress.progressClick(function(value){ 262 console.log("进度点0001"); 263 player.musicSeekTo(value); 264 }); 265 progress.progressMove(function(value){ 266 player.musicSeekTo(value); 267 }); 268 //声音条 269 var $musicVoiceBar=$(".music_voice_bar"); 270 var $musicVoiceLine=$(".music_voice_line"); 271 var $musicVoiceDot=$(".music_voice_dot"); 272 voiceProgress=new Progress($musicVoiceBar,$musicVoiceLine,$musicVoiceDot); 273 voiceProgress.progressClick(function(value){ 274 console.log("声音点0001"); 275 player.musicVoiceSeekTo(value); 276 }); 277 voiceProgress.progressMove(function(value){ 278 player.musicVoiceSeekTo(value); 279 }); 280 } 281 282 });
    View Code

    备注

    人活着,就是要做自己喜欢的事情。无忧,无虑,无怨,无悔。打造一款属于自己的音乐播放器,听歌也会别有一番风味。

    你可能感兴趣的:(jQuery仿QQ音乐播放器)