利⽤jQuery实现⾳乐播放
本⼈挺喜欢⾳乐,⼀直有个想法实现⼀个⾳乐播放器,之前⼀直都在积累知识,学习了原⽣JS和jQuery库。现在觉得是时候了,因此这次利⽤jQuery库来实现。
这个⾳乐播放器现在实现的主要有以下功能:
在主页⾯点击播放歌曲
页⾯底部点击可以跳到播放页⾯,页⾯底部的播放按钮也能控制⾳乐播放/暂停;
播放页⾯⾃制进度条;
主页⾯轮播图特效;
上⼀曲,下⼀曲功能,循环播放模式的实现,以及点击列表按钮显⽰播放列表;
在线搜索⾳乐,得到搜索结果,并播放。
界⾯实现
主页⾯
冯小刚脸
主页⾯是仿其他⽹页⾳乐播放器的,效果如图:
上⾯有⼀个导航条可以切换到其他功能页⾯,下⽅是⼀个Footer,点击之后切换到播放界⾯。
播放页⾯
实现了播放模式(单曲循环、随机播放、循环播放),上⼀曲、下⼀曲、播放/暂停以及⾳乐播放列表的呈现。
搜索页⾯
搜索歌曲可以得到对应的歌曲列表,点击之后开始播放。
实现
⾳乐播放的功能主要依赖的是H5标签。其有以下⼏个属性是⽐较重要的:
src : 播放的⾳频源;
autoplay: ‘autoplay’ 定义⾃动播放;
loop : ‘loop’ 定义循环播放;
controls: ‘controls’ 显⽰播放控件
另外,audio也有很多事件属性,利⽤这些事件属性可以实现该⾳乐播放器⾳频的播放交互效果。⽐如:
Media事件中的 oncanplay事件,onended事件,onpause和onplay事件等等,详细可参考。
1. 主界⾯的实现
主要⽤了⼀个隐藏的audio标签;
在window下监听mousemove事件,通过⿏标的移动来设置导航栏的显⽰,并在导航栏监听mouseleave事件,设置导航栏的隐藏;
封装了⼀个图⽚轮播的插件;double j
播放列表的实现(数组中初始存了⼀些⾳乐);
Footer布局实现。
主要需要详细说的有两个:轮播插件和播放列表的实现。
jQuery插件的编写⼤都是下⾯这个模板:
如果是全局插件的话
;(function($){
$.extend({
函数名: function(){
//⼀些处理操作
}//这是⼀个全局插件,即通过jQeury.函数名可以直接调⽤的
});
})(jQuery)
如果是对象插件:
越来越不懂
;(function($){
$.fn.extend({
函数名: function(){
//函数实现体
}
});  //对象插件顾名思义,是某个特定对象调⽤的⽅法
})(jQuery)
因此,⾸先实现了在页⾯中展⽰轮播的效果:
主要思路:每隔⼀段时间,改变图⽚的透明度,并改变图⽚上⼀层的⿊点与⽩点效果;
var Url = "MusicPlayerImg/";
var LunboArr = ["Music.jpg", "music3.PNG","music2.PNG", "music4.PNG","music5.PNG", "music6.PNG"];
var i = 0;
$("#trueImg").fadeTo(1000, 0.2);
setInterval(function(){
$("#trueImg").fadeTo(1000, 1);
$("#circles img").each(function(index, el) {
$(this).attr('src', 'MusicPlayerImg/⿊点.png');
});
$("#trueImg").attr('src', Url + LunboArr[(i + 1) % 6]);
var selector = "#circles img:eq(" + ((i + 1) % 6) + ")";
$(selector).attr('src', 'MusicPlayerImg/⽩点.png');
i++;
$("#trueImg").fadeTo(1000, 0.2);
}, 2000);
随后将其封装成⼀个div对象插件:
;(function($){
$.fn.extend({
lunbo: function(){
var Url = "MusicPlayerImg/";
var LunboArr = ["Music.jpg", "music3.PNG","music2.PNG", "music4.PNG","music5.PNG", "music6.PNG"];
var i = 0;
音乐导航
$("#trueImg").fadeTo(1000, 0.2);
setInterval(function(){
$("#trueImg").fadeTo(1000, 1);
$("#circles img").each(function(index, el) {
$(this).attr('src', 'MusicPlayerImg/⿊点.png');
});
$("#trueImg").attr('src', Url + LunboArr[(i + 1) % 6]);飒蜜
var selector = "#circles img:eq(" + ((i + 1) % 6) + ")";
$(selector).attr('src', 'MusicPlayerImg/⽩点.png');
i++;
$("#trueImg").fadeTo(1000, 0.2);
}, 2000);
}
});
})(jQuery)
将上⾯⽂件命名成jQuery.lunboValidate.js,并在script标签中引⼊,即可调⽤对应⽅法。
播放列表主要是通过⼀个数组来存储歌曲的信息,然后将其以DOM节点加⼊到HTML⽂档中。数组的形式如下:
arrMusic = [
{
MusicUrl: '',
MusicImg:'',
Singer: '',
MusicName: ''
}
];
数组⾥⾯每⼀个元素都是⼀个对象,这些对象都有着相同的属性,包括⾳乐源,专辑图⽚,歌曲名称以及歌⼿。播放列表的渲染直接读取数组中各个元素的属性就可以得到。
下来点击列表中每个条⽬,都会触发audio的源src改变,并播放。因为列表条⽬可能很多,不可能每⼀个都加⼀个click事件处理函数,所以采⽤事件委托的⽅式进⾏事件监听,即在ul元素上进⾏事件监听,当click事件发⽣时,通过e.target去判断点击的是哪⼀个列表条⽬,从⽽改变成对应的src。audio的src的改变,会触发oncanplay事件,并且还要改变后⾯播放页⾯的图⽚以及进度条进度。
主页⾯底部的Footer,点击之后会进⼊播放界⾯,通过将该页⾯隐藏,显⽰播放页⾯即可。
2. 播放界⾯
这个界⾯的构成很简单,只有⼀个进度条,显⽰进度的⼩圆点,上⽅⼀个Div显⽰播放Img, 以及下⼀曲上⼀曲等这些图⽚。但是这个页⾯的逻辑很复杂,JS的操作很多。
我们可以跟着下⾯⼏个问题处理这些逻辑:
播放歌曲时,⼩圆点如何显⽰进度?
点击进度条某个位置,如何实现播放对应位置的⾳频?
当歌曲播放完之后如何⾃动切换到下⼀曲?
设置不同的播放模式之后歌曲如何去切换?
点击上⼀曲、下⼀曲事件处理程序是如何处理?
点击播放列表显⽰什么?如何将正在播放的歌曲标注出来?
按着这个思路⼀步步实现,其实就可以实现⾳乐播放器的基本功能了。
下⾯我只写⼀些⾃⼰在解决这些问题时的思路。
第⼀个问题: 播放歌曲时,总会触发oncanplay事件,因此在该事件处理程序中,起⼀个定时器,每隔⼀秒使⼩圆点向右⼀个步长即可。那么这个步长⼜如何得到?当⾳乐播放时,可以得到audio的duration属性,这个属性表⽰整⾸歌的总时长,利⽤总时长和进度条的长度就可以得到步长。
第⼆个问题:⿏标点击事件的事件对象有⼀个属性:pageX,pageY表⽰当前点击位置的离浏览器左边界和上边界的距离。利⽤这个距离和进度条的距离只差可以得到⼩圆点应该在的位置的left值。同时还要改变歌曲的播放进度。这要⽤到audio的currentTime属性,单位为秒。同样利⽤距离与步长的商来求时间。
第三个问题:歌曲播放结束时会触发事件onended,因此所有结束之后需要做的操作都可以写到onended事件处理函数中。
第四个问题: 切换包括上⼀曲,下⼀曲,播放结束时下⼀曲应该播放哪⼀⾸?所以需要在点击上⼀曲,下⼀曲按钮时,判断当前的播放模式然后再做操作,另外,在播放结束时的onended事件处理程序中也要判断播放模式。
第五个问题:歌曲切换上⼀曲下⼀曲时,要做这么⼏件事:⼀个是⾳频的src需要变,另⼀个就是在视觉上看起来是重新播放⼀⾸歌。
第六个问题:点击播放列表时,事件处理程序需要做的是,将数组中的歌曲信息读取并渲染到页⾯上,同时对正在播放的歌曲进⾏特殊颜⾊标注。
在实际实现的过程中,遇到⼀个问题:⽆论是点击进度条,还是切换下⼀曲,都会出现时间不是⼀秒
⼀秒的变化。分析了原因之后,是每次触发oncanplay事件时,都会起⼀个定时器,这样就是造成计时出现错乱的情况。因此解决⽅法就是点击进度条时先clearInterval()。
需要注意的是:⽹易云⾳乐的API地址与页⾯是不同源的,因此涉及到跨域,本次利⽤jQuery库提供的JSONP跨域⽅法,将aJax请求中的dataType设为jsonp即可。
$.ajax({
url: URI,
type: 'get',
dataType: 'jsonp',
jsonp : 'callback',
jsonCallback : 'jsonCallback',
success: function(data){
/*console.sult.songs[0]);*/
for(var i = 0; i < sult.songs.length; i++)
{
var jsondata = sult.songs[i];
console.log(jsondata);
$("#results").append($("<p>" + jsondata.name + "<span>" + jsondata.artists[0].name + "</span>" + "<b class='source' style='display:none'>"
}
}
})
血荐轩辕主题曲