本人挺喜欢音乐,一直有个想法实现一个音乐播放器,之前一直都在积累知识,学习了原生JS和jQuery库。现在觉得是时候了,因此这次利用jQuery库来实现。

这个音乐播放器现在实现的主要有以下功能:

  • 在主页面点击播放歌曲;
  • 页面底部点击可以跳到播放页面,页面底部的播放按钮也能控制音乐播放/暂停;
  • 播放页面自制进度条;
  • 主页面轮播图特效;
  • 上一曲,下一曲功能,循环播放模式的实现,以及点击列表按钮显示播放列表;
  • 在线搜索音乐,得到搜索结果,并播放。

界面实现

  • 主页面

主页面是仿其他网页音乐播放器的,效果如图:

jquery网页 jquery网页底部音乐播放器_jquery

上面有一个导航条可以切换到其他功能页面,下方是一个Footer,点击之后切换到播放界面。

  • 播放页面

    实现了播放模式(单曲循环、随机播放、循环播放),上一曲、下一曲、播放/暂停以及音乐播放列表的呈现。
  • 搜索页面

jquery网页 jquery网页底部音乐播放器_jquery_02

搜索歌曲可以得到对应的歌曲列表,点击之后开始播放。

实现

音乐播放的功能主要依赖的是H5标签。其有以下几个属性是比较重要的:
src : 播放的音频源;
autoplay: ‘autoplay’ 定义自动播放;
loop : ‘loop’ 定义循环播放;
controls: ‘controls’ 显示播放控件

另外,audio也有很多事件属性,利用这些事件属性可以实现该音乐播放器音频的播放交互效果。比如:
Media事件中的 oncanplay事件,onended事件,onpause和onplay事件等等,详细可参考W3C上的文档。

  1. 主界面的实现
    主要用了一个隐藏的audio标签;
    在window下监听mousemove事件,通过鼠标的移动来设置导航栏的显示,并在导航栏监听mouseleave事件,设置导航栏的隐藏;
    封装了一个图片轮播的插件;
    播放列表的实现(数组中初始存了一些音乐);
    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()。

3.搜索页面
搜索页面的构成也非常简单,主要是在文本框中输入搜索关键字,点击按钮之后搜索对应歌曲。 本次采用网易云音乐的API来请求歌曲信息。其中,type,limit和s参数是可以设置的.
type:
type = 1 单曲
type = 10 专辑
type = 100 歌手
type = 1000 歌单
type= 1002 用户
limit: 限制搜索得到的数量
s: 关键字

需要注意的是:网易云音乐的API地址与页面是不同源的,因此涉及到跨域,本次利用jQuery库提供的JSONP跨域方法,将aJax请求中的dataType设为jsonp即可。

$.ajax({
    url: URI,
    type: 'get',
    dataType: 'jsonp',
    jsonp : 'callback',
    jsonCallback : 'jsonCallback',
    success: function(data){
        /*console.log(data.result.songs[0]);*/
        for(var i = 0; i < data.result.songs.length; i++)
        {
            var jsondata = data.result.songs[i];
            console.log(jsondata);
            $("#results").append($("<p>" + jsondata.name + "<span>" + jsondata.artists[0].name + "</span>" + "<b class='source' style='display:none'>" + jsondata.audio + "</b><b style='display:none'>" + jsondata.album.name + "</b><b style='display:none'>" + jsondata.album.picUrl + "</b></p>"));
        }
    }
})

当请求成功时,将返回的数据解析渲染到页面中。当然,这里需要了解返回的数据格式。

jquery网页 jquery网页底部音乐播放器_javascript_03


返回的数据渲染到页面中之后,点击对应的条目又会触发播放,即将audio src属性设置,并对进度条上小圆点位置进行初始化设置等等。

到这,音乐播放器的基本功能都实现了,下来想说的一点是:
本次实现对一些公共的函数以及全局变量都进行了封装,将他们封装成插件来使用,一个好处是避免了代码的多次重复;另一个是增强了可维护性。

希望源代码的可以留言,希望大家可以共同进步。