欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

jQuery仿QQ音乐播放器

程序员文章站 2022-08-09 17:12:03
本文通过Html+CSS+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音乐播放器

 

 

 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);

歌词模块【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);

进度条模块【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);

加载流程,包括初始化歌曲列表,歌词信息,注册事件,初始化进度条等功能,本例中的歌曲列表和歌词信息,均是通过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 = $("<li class=\"list_music\">\n" +
 61             "<div class=\"list_check\">\n" +
 62             "<i></i>\n" +
 63             "</div>\n" +
 64             "<div class=\"list_number\">\n" +
 65             (index + 1) +
 66             "</div>\n" +
 67             "<div class=\"list_name\">\n" +
 68             music.name +
 69             "<div class=\"list_menu\">\n" +
 70             "<a href=\"javascript:;\" title=\"播放\" class=\"list_menu_play\"></a>\n" +
 71             "<a href=\"javascript:\;\" title=\"添加\"></a>\n" +
 72             "<a href=\"javascript:;\" title=\"下载\"></a>\n" +
 73             "<a href=\"javascript:;\" title=\"分享\"></a>\n" +
 74             "</div>\n" +
 75             "</div>\n" +
 76             "<div class=\"list_singer\">\n" +
 77             music.singer +
 78             "</div>\n" +
 79             "<div class=\"list_time\">\n" +
 80             "<span>\n" +
 81             music.time +
 82             "</span>\n" +
 83             "<a href=\"javascript:;\" title=\"删除\" class=\"list_menu_del\"></a>\n" +
 84             "</div>\n" +
 85             "</li>");
 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=$("<li>"+ele+"</li>");
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 });

备注

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

源码链接