vue实战开辟016,怎样高效做1个HTML5运动播放器

自家近日备选利用闲暇时光构建3个完整的音乐播放器项目,首要用以学习及享受!原创不易,转发请注脚出处。

这段时日公司一向在做二个PC的教诲类单页应用,庞大复杂,涉及特别多H伍的文化,音频便是内部的1部分。前几日偷风暴的空闲时写了叁个运动音乐播放器,作为练手项目(存放在码云)。若你以为该文章对你有扶助,别忘了点个赞啦。

日前作者在Vue中援引了Font Awesome字体Logo,Font
Awesome近来创收外汇了6柒拾二个Logo(那么些是可缩放的矢量Logo,可以通过CSS样式来改动Logo的大小、颜色、阴影或然其余任何帮衬的成效),绝对element来讲还算挺多的,前些天我们再来使用二个图库更全的方案,那正是Ali提供的iconfontLogo库,那么些是方今境内最为强劲的矢量Logo库宗旨,里面包括非常丰裕的矢量Logo库提供下载。

     
 那是2个怎么着的音乐播放器呢?全体的架构跟酷狗大概吧,笔者的主意啊,是一个个组件三个个模块先做好,最后组合成完整的品类,最终项目会放在本身的github上,等品类扫尾后会发布链接。别的呢,这些好不轻巧对自身已经封装过的函数的片段检查,为了便利原理上的询问,整个项目不会用到此外的控件及插件,算是从最底层的js或jq+audio初步吧(实际开销不引入,那样作用太低,可是用于升高本人的依旧引入那样,写过叁遍跟引用二遍是全然差别三个概念),当然也会方便的封一些函数,这个会放在小说的最末尾,每种模块或多或少都会引用个中部分函数。

在线地址:请猛击这里
源码:请猛击这里

必发365手机版 1

模块1、歌词同步:(为了便于测试,先用了html5提供好的audio标签,大家只做歌词效用),开首效果是那样:(其它直接在酷狗下载歌词文件就足以用了)

必发365手机版,注意:运用PC浏览最佳张开活动设备情势,使用移动器具浏览须求关闭无痕浏览情势(不然不可能运用本地存款和储蓄,一般浏览器都以暗许不张开),项目须要在本地服务器线上服务器运营,以file:///格局的地方展开是无力回天开展ajax请求的,从而不能见到音乐数据。

大家进iconfont官方Logo库,找到本身想要使用的Logo字体,然后将其进入购物车中甄选下载至地点,iconfont有个便宜那正是足以自行选取所需的书体然后生成对应的书体样式,这样能够减弱过多用不到的书体代码,缩小代码(为了越来越好的管制大家得以建个档期的顺序来特地存放对应的书体Logo)。

必发365手机版 2

品类落到实处的职能及所用知识

必发365手机版 3

     
 这些其实简单,不过呢,咱用点最笨的主意(关于剖析字符串,不用正则相配),酷狗都用过啊,里面包车型地铁歌词文件是.krc文件,这种文件是加密过的,所以呢,从酷狗下载下来的歌词文件需求先转化成lrc文件,推荐上边包车型大巴软件:

  • 播放器的基础操作,上1首,下壹首(顺序播放、随机播放、单曲循环),播放暂停,滑动时间轴的乐章定位
  • 初步handlebar模板渲染音乐列表数据,下拉滚动加载音乐列表数据。
  • 歌曲列表可加多保养音乐,于后一次刷新时更新喜爱音乐列表,基于HTML5本土存款和储蓄。
  • 布局选择rem布局,自适应移动端手提式有线电话机配备。
  • iconfont在线图标应用的应用

下载之后我们到了三个iconfont字体压缩包,里面富含了字体和体裁等文件和二个dome实例,不一样的文本能够凭借分裂的急需来采用,这里大家能够参谋dome_index.html提示来操作,里面为大家提供了各个应用方法,如Unicode引用、Font
class引用、Symbol引用。

必发365手机版 4

项目目录文件结构
css:寄存样式文件
lib:存放公共脚本库
js:存放项目脚本文件
img:存放图片
fonts:花色字体文件
res:品类音乐财富
ui:项目ui文件(psd)

必发365手机版 5

krc文件点开是那般的:

// ============================配置变量================================
var rootPath = window.location.href.replace(/\/\w+\.\w+/, "/");
var Settings = {
playmode: 0, //0列表循环,1随机,2为单曲循环
volume: 0.5, //音量
initNum: 10, //列表初始化歌曲数
reqNum: 10 //后续请求歌曲数
};

// ============================工具函数================================
var Util = (function() {
return {

}
})()
// ============================Dom选择器================================
var Dom = {

}

// ============================全局变量================================
var winH = $(window).height();

var songNum = 0; //当前列表歌曲数目
var lrcHighIndex = 0; // 歌词高亮索引
var lrcMoveIndex = 0; // 歌词移动单位索引
var moveDis = 0; // 单句歌词每次移动距离

var duration = 0; // 当前歌曲的时间
var index = 0; //当前播放歌曲的索引
var songInfo = null; // 当前歌曲信息
var songModelUI = null; // 当前歌曲UI模型
var timeArr = []; //当前歌曲时间数组
var formatTimeArr = []; //当前歌曲时间数组(格式化为秒数)

// ============================入口函数================================
function main() {
initUIFrame();
var initModel = PlayerModel();

var songListUI = ModelUIFrame(Dom.songListContainer);
var lsongListUI = ModelUIFrame(Dom.lSongListContainer);
initModel.getSongList("data/data.json", function(data) {
// 生成所有歌曲列表
songListUI.renderList(data, 0, null, function() {
songListUI.updateList();
});
// 生成喜爱歌曲列表
initModel.getLoveSongArr(function(lSongArr) {
lsongListUI.renderList(data, 1, lSongArr);
});
// 添加动画
Util.addAnimationDelay(Dom.song);
// 保存歌词数据
initModel.saveLyric(data);

});
EventHandler();
}
// ============================初始化UI函数================================
function initUIFrame() {

}
// ============================实现数据交互方法================================
function PlayerModel() {

}
// ============================模型动态UI模块================================
function ModelUIFrame(container) {

}
// ============================事件绑定模块================================
function EventHandler() {

}
// 调用入口函数
main();

在品种中的assets中新建三个iconfont目录,把除了dome以外的weni文件都放入该目录,然后在main.js中全局引进css文件,通过import
‘./assets/iconfont/iconfont.css’ 引进就能够。

必发365手机版 6

作用点详解
Handlebar.js初次渲染及滚动加载
应用前端模板优点是把数据和结构分离出来,代码更清晰。但新兴意识handlerbar.js就如不能在js中示范模板对象,而html中的handlebar在初次进入页面便会被编写翻译了,由此后续增添音乐依旧利用古板的拼接字符串的措施,假让你有更优雅的动态加载格局,招待研讨调换。

必发365手机版 7

转化成lrc文件后是那般的:

html:handlebars模板包罗在script标签之中并且type类型为”text/x-handlebars-template”,在开端化页面包车型地铁时候依照js获取数据植入后就渲染出相应的html。

若是你想对Logo做适当的调动大家得以在项目中对我们的Logo实行适宜的修改,如图中所示,调节职分、大小、方向、色彩等,特别的方便快捷。

必发365手机版 8

<script id="sListTpl" type="text/x-handlebars-template">
{{#each this}}
{{#isInitData this @index}}
<li class="song btm-line" data-src={{songSrc}} data-index={{id}}>
    <div class="poster">
        <img src={{poster.thumbnail}}>
    </div>
    <div class="songinfo">
        <h2 class="lsongname">{{songName}}</h2>
        <sub class="lsinger">{{singer}}</sub>
    </div>
    <div class="loveflag">
        <i class="icon icon-love {{#if loveFlag}}active{{/if}}"></i>
    </div>
</li>
{{/isInitData}}
{{/each}}
</script>

必发365手机版 9

小心那时候lrc文件的字符编码不是utf-八,各位供给活动另存为utf-八文件,好了,歌词文件希图好了,能够开头大家的乐章模块了。

js:

接下去我们就足以在您想要使用的其余省方引用那一个iconfont字体Logo了,小编比较欣赏用Font
class来引进字体Logo,所以那边大家使用 Font class方法来引进字体图标,在等级次序中得以看出各样图标都有照应的代码名,我们即使在必要的地点通过3个i标签来引用那么些Logo就能够,如:

css及js文件小编全部位于html里,完善后会逐步封装,css会选拔less替代。

function renderAllList(data) {
    var preTpl;
    var lsongArr = Util.getItem('lsonglist') === null ? [] : JSON.parse(Util.getItem('lsonglist'));
    // 生成列表
    if (!sListTpl) {
        // 后续动态生成歌曲
        var tpl = "";
        var songIndex = songNum;
        $.each(data, function(index, el) {
            if (index >= songIndex && index < songIndex + Settings.reqNum) {
                tpl += "<li class='song btm-line' data-src='res/music/" + songNum + ".mp3' data-index='" + songNum + "'><div class='poster'>[站外图片上传中……(1)]</div><div class='songinfo'><h2 class='lsongname'>" + el.songName + "</h2><sub class='lsinger'>" + el.singer + "</sub></div><div class='loveflag'><i class='icon icon-love '></i></div></li>";
                songNum++;
            }
        });
        $(container).append($(tpl));
    } else {
        // 首次生成歌曲
        preTpl = Handlebars.compile(sListTpl);
        $(container).html(preTpl(data));
    }
    // 更新喜爱图标
    if (lsongArr.length !== 0) {
        $.each(lsongArr, function(index, val) {
            Dom.songListContainer.find(".song").eq(val).find(".icon-love").addClass('active');
        });
    }
}

(后边要加iconfont哦,不然不只怕辨识),这样自身能够将该Logo引进项目中利用了。

 

rem布局自适应方案
差不多上指的是html根成分上定义3个字体大小,然后css样式定义时行使rem作为单位,包罗margin、paddding、用于相对定位的单位等等。然后js根据手提式有线电话机设备的显示屏尺寸,改动根字体的大小,那样全体页面也会随之相应的裁减或加大。
越来越多详解,请看那一篇小说《移动端自适应布局消除方案——rem》,您能够碰撞这里跳转。

必发365手机版 10

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>基于js的更高级常用函数封装</title>
  6     <script src="../js/jquery-3.3.1.min.js" type="text/javascript"></script>
  7     <script src="../js/mine/dc-handle-function.js" type="text/javascript"></script>
  8     <style>
  9         .preload{
 10             width:200px;
 11             height:100px;
 12             position:absolute;
 13             top:35%;
 14             left:40%;
 15         }
 16         .preload img{
 17             width:100%;
 18             height:100%;
 19         }
 20         .lyric{
 21             width:400px;
 22             height:500px;
 23             margin:0 auto;
 24             display:none;
 25             overflow-y:auto;
 26             overflow-x:hidden;
 27             font:18px "华文楷体";
 28             color:black;
 29             text-align: center;
 30             box-shadow:-2px 2px 15px #fff;
 31             background:rgba(0,255,255,0.3);
 32         }
 33         .music{
 34             width:400px;
 35             margin:0 auto;
 36         }
 37         .music audio{
 38             width:100%;
 39         }
 40         body{
 41             overflow:scroll;
 42             background:url("../resource/bg.jpg") fixed no-repeat;background-size:cover;
 43         }
 44     </style>
 45     <script>
 46         $(function(){
 47             dorseyHf.dc_ajax_g('../resource/av/ChiQingZhong1.lrc?t='+new Date().getTime(),
 48                     function(str){
 49                         //这个函数以后也是会封装的。
 50                         var str1=str.split("[");
 51                         var str2=[];
 52                         var lyric=$(".lyric");
 53                         for(var i=1;i<str1.length;i++){
 54                             str2[i-1]=str1[i].split("]");
 55                         }
 56                         for(let i=0;i<str2.length;i++){
 57                             if(lyric.children('p').length==0){
 58                                 lyric.append('<p></p>');
 59                             }
 60                             lyric.children('p').eq(i).html(str2[i][1]);
 61                             lyric.append('<p></p>');
 62                         }
 63                         lyric.css("display","block");
 64                         //str3: "00:00.09",即获取到歌词的前半部分[时间];
 65                         var str3=[],str4=[],str5=[];
 66                         for(var i=2;i<str2.length;i++){
 67                             str3[i-2]=str2[i][0];
 68                         }
 69                         //str4:  str4[i][0]="00";str4[i][1]="00.09"
 70                         //str5:计算str4转化后min:sec的值,单位(s),用于后续与当前时间比较。
 71                         for(var i=0;i<str3.length;i++){
 72                             str4[i]=str3[i].split(":");
 73                             str5[i]=(parseFloat(str4[i][0])*60)+parseFloat(str4[i][1]);
 74                             console.log("p"+i+":"+lyric.children('p').eq(i+2).offset().top);
 75                         }
 76                         $('audio').on("timeupdate",function(){
 77                             var scale=this.currentTime;
 78 //                            var k=[];
 79                                 for(var i=0;i<str5.length;i++){
 80                                     if(scale>=str5[i]){
 81                                         lyric.children('p').eq(i+2).css("color","red").siblings().css("color","");
 82                                         lyric.children('p').eq(i+2).css("transform","scale(1.4)").
 83                                         siblings().css("transform","");
 84                                         k[i]=i;
 85 //                                      lyric.scrollTop(lyric.children('p').eq(i).offset().top);
 86                                     }
 87                                 }
 88 //                            var music=k.length;
 89 //                            console.log(music+": "+lyric.children('p').eq(music).offset().top);
 90                         });
 91             },$('img'));
 92         })
 93     </script>
 94 </head>
 95 <body>
 96 <div class="music">
 97     <audio src="../resource/av/ChiQingZhong.mp3" controls="controls"></audio>
 98 </div>
 99 <div class="preload">
100     <img src="../resource/preload.gif" alt="必发365手机版 11">
101 </div>
102 <div class="lyric">
103 </div>
104 </body>
105 </html>

至于歌词的联合具名方案完成
脚下音乐播放器的歌词同步展现大致有二种,1种是规范到单个文字,壹种是规范到单行歌词。本文达成的是第1种。

除了这一个之外Font class的章程,还足以选取Unicode和Symbol来引用,拿Unicode来讲,
使用时需在app.vue中设置全局样式,引进iconfont文件有关,每种Logo有相应的字符编码,在动用的时候我们引进字符编码就可以,具体的能够参照demo_index.html,里面写的很详细,还有Symbol引用方法。

 

总体完成思路
页面初步化时,请求歌曲数量json(本地json文件模拟),个中歌名、歌星、图片等按需渲染到html中,将歌词存款和储蓄到localStorage中。此时,F1二展开chrome调节和测试器,进入Application-LocalStorage能够观看:

必发365手机版 12

 

点击一首歌进入播放页面后,歌词就能够从本地存款和储蓄中读取,此时你会看到变化这样的乐章结构:

 

每1行歌词都快要将歌词时间绑定在data-point上,监听歌曲播放的timeupdate事件,当歌曲的光阴(经过取整管理)与当前data-point值相等时,就为当前歌词高亮(也就是给p增加current类名),并且依据当下高亮歌词的index索引将一切歌词盒子向上移动p标签的可观+margin-top的可观

 这里须求引用一些封装函数,需引进dorseyHf类库(这里不贴了请看最后面),jq的压缩版自行百度:

lrc歌词的组织
起点腾讯网云音乐的乐章数据:

 

[00:14.64]如果不是那镜子\n[00:16.73]不像你不藏秘密\n[00:21.26]我还不肯相信\n[00:23.02]没有你我的笑更美丽\n[00:28.99]那天听你在电话里略带抱歉的关心\n

[00:16.959]摘一颗苹果\n[00:19.800]等你从门前经过\n[00:22.700]送到你的手中帮你解渴\n[00:25.570]像夏天的可乐\n

[00:00.00] 作曲 : 周杰伦\n[00:01.00] 作词 : 周杰伦\n[00:05.620]\n[00:37.980]亲吻你的手\n

 模块二、音乐盒之基本作用——播放暂停,上下首切换,歌曲详细情况,歌曲播放进程(可随心所欲拖动),自动列表循环播放。

能够见到格式 = [时间点] + 要来得的文字 + \n
此处有七个坑必要专注:
一些歌词秒数是准确到小数点后两位局地是二位
一对歌词(周杰伦(Zhou Jielun)《算怎么男生》)格式是[时间点]+\n

无意快壹点了,时间过得好快,这么些项目标左侧是音乐盒,右边是开始展览,音乐盒是这么:

日子歌词创立映射
首先以\n将歌词字符串分割成以[时间点]文字的数组,但鉴于那样分割之后最终五个成分是空的,所以用tempArr.splice(-1,
1)
去除最终三个成分。
接下去循环遍历那些一时数组,由于地方提到的秒数准确度的标题,所以判别一下index为玖是还是不是为数字,若为数字则将该位数字删除。(采纳字符串截取形式,若你对js字符串方法不了然,能够碰撞这里)
由此如此的拍卖现在,偶尔数组的因素格式不再有分别了,此时再开始展览字符串截取,将截取到的日子点放入timeArr,将截取的乐章放入lyricArr,并以再次来到保存着那多少个变量的对象。

必发365手机版 13

function createArrMap(lyric) {
    var timeArr = [],
        lyricArr = [];
    var tempArr = lyric.split("\n");
    tempArr.splice(-1, 1);
    var tempStr = "";
    $(tempArr).each(function(index) {
        tempStr = this;
        if (tempStr.charAt(9).match(/\d/) !== null) {
            tempStr = tempStr.substring(0, 9) + tempStr.substring(10);
        }
        timeArr.push(tempStr.substring(0, 10));
        lyricArr.push(tempStr.substring(10));
    });
    return {
        timeArr: timeArr,
        lyricArr: lyricArr
    };
}

算上开始展览作用差不离是如此:

变化歌词
出于地点歌词格式产生时间点对应的歌词为空,此时只要渲染出1个
标签的冲天将为0,那会影响歌词向上移动距离的不联合。由此下边作出个推断如若为空,则替换为“————–”。(为空的时候大繁多是歌曲其中停顿或过渡的时候)

必发365手机版 14

function renderLyric(songinfo) {
    var arrMap = Util.createArrMap(songinfo.lyric);
    var tpl = "";
    $.each(arrMap.lyricArr, function(index, lyric) {
        var lyricContent = lyric === "" ? "--------------" : lyric;
        tpl += "<p class='' data-point='" + arrMap.timeArr[index] + "'>" + lyricContent + "</p>";
    });
    Dom.lrcwrap.html(tpl);
}

是因为笔者不懂UI,配色设计不好请见谅,咱更重视的是效益完毕,废话不多说了。

宋词同步
宋词同步笔者写在了syncLyric方法中,监听audio成分的timeupdate事件调用。
其一法子接收四个参数,第三个是时下播放歌曲时间(秒),第四个是转账为秒数的日子点数组。
一旦当前几天子>=时间点,那么高亮当前歌词(以lrcHighIndex)存款和储蓄,并且lrcHighIndex自增一。
当歌词高亮索引lrcHighIndex>=1即歌词高亮不为第贰句时,总计索引并让歌词盒子向上移动。

必发365手机版 15

function syncLyric(curS, formatTimeArr) {
    if (Math.floor(curS) >= formatTimeArr[lrcHighIndex]) {
        Dom.lrc.eq(lrcHighIndex).addClass('current').siblings().removeClass('current');
        if (lrcHighIndex >= 1) {
            lrcMoveIndex = lrcHighIndex - 2;
            moveDis += Util.getMoveDis(lrcMoveIndex);
            Dom.lrcwrap.animate({
                "top": "-" + moveDis + "px"
            }, 100);
            lrcMoveIndex++;
        }
        lrcHighIndex++;
    }
}

     
伊始构思的时候,整个播放器的Logo照旧相比多的,这里推荐一种相比好的格局——Ali字体iconfont,跟你逛Tmall同样,进入iconfont官方网址后,对你想要的Logo各类买买买,加购物车,当然不用钱的,你再也不用忧虑你男朋友不帮你清空购物车了,增添完购物车的后边呢,那些字体呢有几许种艺术提要求你,做成Logo的png格式,svg格式,jpg格式等等,还有最重大的书人体模型式,你点下载代码就能够了。

下载完解压是这么的:

必发365手机版 16

你只需依据提醒(点开三个html里面大41个看您要用什么格式,那写html能够知晓成人事教育育学文书档案之类的),照着做就足以了。

好了,基本的素材希图好了,伊始我们的代码之旅吧!

html部分:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>dorsey</title>
  6     <link rel="shortcut icon" href="../resource/favicon.ico" type="image/x-icon"/>
  7     <link rel="stylesheet" href="../css/music.min.css" type="text/css">
  8 
  9     <script src="../font/index/iconfont.js"></script><!--阿里字体引入-->
 10     <script src="../dist/jquery-3.3.1.min.js" type="text/javascript"></script><!--jQuery框架引入-->
 11 
 12     <!--动画引入,动画推荐“wow”(该插件兼容性也只是IE10+,有历史遗留的请慎用)-->
 13     <script src="../dist/dc-animate.js" type="text/javascript"></script>
 14 
 15     <script src="../js/music.js" type="text/javascript"></script>
 16 </head>
 17 <body>
 18 <div class="music">
 19     <div class="playerBg"></div>
 20     <div class="player">
 21         <!--这是这个音乐播放器的核心:音乐盒,主要包含的功能模块类似于酷狗左侧那个框,比如列表list,最近播放recentPlay,播放栏
 22         (上下页,开始暂停播放,播放进度,音量,播放方式等等),本地音乐,音乐电台,网络收藏等等-->
 23         <div class="musicBox dc_left">
 24             <div class="header">
 25                 <ul>
 26                     <li class="logo dc_left"><img src="../resource/logo.gif" alt="必发365手机版 17"></li>
 27                     <li class="dc_left"><img src="" class="ver">dorsey</li>
 28                     <li class="dc_right dc_icon">
 29                         <img src="" class="ver">
 30                         <svg class="icon unfold" aria-hidden="true">
 31                             <use xlink:href="#icon-iconzhankai"></use>
 32                         </svg>
 33                         <svg class="icon" aria-hidden="true">
 34                             <use xlink:href="#icon-zuixiaohua3"></use>
 35                         </svg>
 36                         <svg class="icon" aria-hidden="true">
 37                             <use xlink:href="#icon-iconfonticon2"></use>
 38                         </svg>
 39                     </li>
 40                 </ul>
 41             </div>
 42             <!--音乐盒导航,实际上可以看成是一个选项卡-->
 43             <div class="nav">
 44                 <ul>
 45                     <li>
 46                         <img src="" class="ver">
 47                         <svg class="icon" aria-hidden="true">
 48                             <use xlink:href="#icon-yinlemusic214"></use>
 49                         </svg>
 50                     </li>
 51                     <li>
 52                         <img src="" class="ver">
 53                         <svg class="icon" aria-hidden="true">
 54                             <use xlink:href="#icon-guanyuyunguanjia"></use>
 55                         </svg>
 56                     </li>
 57                     <li>
 58                         <img src="" class="ver">
 59                         <svg class="icon" aria-hidden="true">
 60                             <use xlink:href="#icon-xinhaojieshouqi"></use>
 61                         </svg>
 62                     </li>
 63                     <li>
 64                         <img src="" class="ver">
 65                         <svg class="icon" aria-hidden="true">
 66                             <use xlink:href="#icon-shouji"></use>
 67                         </svg>
 68                     </li>
 69                     <li>
 70                         <img src="" class="ver">
 71                         <svg class="icon" aria-hidden="true">
 72                             <use xlink:href="#icon-wenjianjia-zhankai"></use>
 73                         </svg>
 74                     </li>
 75                 </ul>
 76             </div>
 77             <!--音乐盒导航栏每个导航对应的内容:1、音乐列表,2、网络收藏,3、音乐电台,4、链接手机,5、本地音乐-->
 78             <div class="nav_detail">
 79                 <div class="musicList on">音乐列表</div>
 80                 <div class="cloudCollect">网络收藏</div>
 81                 <div class="musicDisk">音乐电台</div>
 82                 <div class="musicMP">手机管理</div>
 83                 <div class="musicLocal">本地音乐</div>
 84             </div>
 85             <!--音乐盒核心部分,播放歌曲,上下首切换,播放进度,音量,播放模式,显示歌词,我喜欢(收藏),下载歌曲,
 86                 更多(暂时没想好,用作拓展用),由于这个模块相对功能较多,我的时间比较零散,所以准备拆分成几个模块来做:
 87                 1、基本功能:播放暂停,上下首切换,播放进度
 88                 2、拓展功能1:播放模式
 89                 3、拓展功能2:歌词显示,歌词模块的代码会改成字符串正则匹配的方式
 90                 4、拓展功能3:音量,下载歌曲
 91                 5、拓展功能4:我喜欢(收藏),更多(看情况吧,可能仅仅只有点击效果,暂时想不到要添加什么)
 92             -->
 93             <div class="musicPlayer">
 94                 <!--<div class="logo1">dorsey</div>-->
 95                 <div class="feature">
 96                     <div class="btn_basic">
 97                         <svg class="icon pre" aria-hidden="true">  <!--上一首按钮-->
 98                             <use xlink:href="#icon-unie622"></use>
 99                         </svg>
100                         <svg class="icon play" aria-hidden="true" style="">  <!--播放按钮-->
101                             <use xlink:href="#icon-bofang"></use>
102                         </svg>
103                         <svg class="icon pause noDisplay" aria-hidden="true">  <!--暂停按钮-->
104                             <use xlink:href="#icon-pause"></use>
105                         </svg>
106                         <svg class="icon next" aria-hidden="true">  <!--下一首按钮-->
107                             <use xlink:href="#icon-unie623"></use>
108                         </svg>
109                         <div>
110                             <!--<hr>-->
111                         </div>
112                     </div>
113                     <div class="others">
114                         <svg class="icon" aria-hidden="true">  <!--收藏按钮-->
115                             <use xlink:href="#icon-like-1"></use>
116                         </svg>
117                         <svg class="icon" aria-hidden="true">  <!--下载按钮-->
118                             <use xlink:href="#icon-xiazai"></use>
119                         </svg>
120                         <svg class="icon" aria-hidden="true">  <!--播放模式按钮-->
121                             <use xlink:href="#icon-danquxunhuan"></use>
122                         </svg>
123                         <svg class="icon" aria-hidden="true">  <!--音量调整按钮-->
124                             <use xlink:href="#icon-mn_shengyin"></use>
125                         </svg>
126                         <svg class="icon" aria-hidden="true">  <!--更多按钮-->
127                             <use xlink:href="#icon-gengduo-copy"></use>
128                         </svg>
129                         <svg class="icon" aria-hidden="true">  <!--歌词文本按钮-->
130                             <use xlink:href="#icon-text3wenben"></use>
131                         </svg>
132                     </div>
133                 </div>
134                 <div class="progressBar">
135                     <div class="time">
136                         贾青-痴情冢
137                         01:16 / 03:22
138                     </div>
139                     
140                         
141                         
142                     
143                 </div>
144             </div>
145             <!--H5音乐播放-->
146             <audio src="../resource/av/贾青-痴情冢.mp3" class="audio"></audio>
147         </div>
148         <!--这部分是整个音乐播放器的拓展,如歌词,音效,播放队列,一键换肤,一键收起展开等等后续想到再一一补充-->
149         <div class="extensions dc_left">
150             拓展功能
151         </div>
152     </div>
153 </div>
154 </body>
155 </html>

css

body,dd,div,dt,h1,h2,h3,h4,h5,h6,html,li,ol,p,span,table,ul{margin:0;padding:0}li,ul{list-style:none}a{text-decoration:none}.dc_left{float:left}.dc_right{float:right}.dc_clear{content:"";display:block;clear:both}.dc_mar_center{margin:0 auto}.dc_title{font:30px 华文楷体;color:red;text-align:center;text-shadow:0 0 3px #7e0000}.dc_pointer{cursor:pointer}.dc_c_red{color:red}.icon{width:1.5em;height:1.5em;vertical-align:-.15em;fill:currentColor;overflow:hidden;color:#fff;cursor:pointer;transition:.5s}.icon:hover{transform:scale(1.5)}.music{width:1000px;height:600px;margin:50px auto 0;position:relative}.playerBg{width:100%;height:100%;position:absolute;opacity:.3}.ver{width:0;height:100%;vertical-align:middle;visibility:hidden}.player{width:100%;height:100%;position:absolute;color:#fff}.player .musicBox{width:30%;height:100%;box-shadow:-1px 1px 10px #fff;-webkit-box-shadow:-1px 1px 10px #fff;-moz-box-shadow:-1px 1px 10px #fff;-o-box-shadow:-1px 1px 10px #fff}.player .musicBox .header{width:100%;height:8%;background:rgba(255,255,255,.3)}.player .musicBox .header ul{width:100%;height:100%}.player .musicBox .header li{height:100%;font:15px "Times New Roman";box-sizing:border-box}.player .musicBox .header .logo{width:12%;height:100%;margin-left:10px}.player .musicBox .header .logo img{margin-top:8%;width:100%;height:80%}.player .musicBox .header .dc_icon{text-align:right;padding:2%}.player .musicBox .header .dc_icon .icon{width:1.2em;height:1em}.player .musicBox .nav{width:100%;height:6%;background:rgba(255,255,255,.2)}.player .musicBox .nav ul{width:100%;height:100%;margin-left:-1%}.player .musicBox .nav li{width:20%;height:100%;box-sizing:border-box;text-align:center;padding:2%;float:left}.player .musicBox .nav li .icon{color:#6fff2d}.player .musicBox .nav_detail{width:100%;height:70%;background:rgba(255,255,255,.1);position:relative}.player .musicBox .nav_detail div{width:100%;height:100%;position:absolute;font:50px "华文楷体";text-align:center;line-height:400px;display:none}.player .musicBox .nav_detail .on{display:block}.player .musicBox .musicPlayer{width:100%;height:16%;background:rgba(255,255,255,.2)}.player .musicBox .musicPlayer .feature{width:100%;height:60%;padding:.5em;box-sizing:border-box}.player .musicBox .musicPlayer .feature .btn_basic{width:50%;height:100%;float:left;padding:.75em 0;box-sizing:border-box}.player .musicBox .musicPlayer .feature .btn_basic .pause,.player .musicBox .musicPlayer .feature .btn_basic .play{transform:scale(2);margin:0 1em}.player .musicBox .musicPlayer .feature .btn_basic .noDisplay{display:none}.player .musicBox .musicPlayer .feature .others{width:50%;height:100%;float:left;text-align:right;padding:1em 0;box-sizing:border-box}.player .musicBox .musicPlayer .feature .others .icon{width:1em;height:1em}.player .musicBox .musicPlayer .progressBar{width:90%;height:30%;margin:1% 5% 5%;transition:all .2s;position:relative;box-sizing:border-box}.player .musicBox .musicPlayer .progressBar .time{width:100%;font:12px "Times New Roman";margin-bottom:2px}.player .musicBox .musicPlayer .progressBar .time:after{content:"";display:block;clear:both}.player .musicBox .musicPlayer .progressBar .barBg{position:absolute;width:100%;height:3px;background:#ccc;border-radius:1.5px 1.5px 1.5px 1.5px;-webkit-border-radius:1.5px 1.5px 1.5px 1.5px;-moz-border-radius:1.5px 1.5px 1.5px 1.5px}.player .musicBox .musicPlayer .progressBar .barFg{position:absolute;width:100px;height:3px;background:linear-gradient(to left,#438aff,#cdfff7);border-radius:1.5px 1.5px 1.5px 1.5px;-webkit-border-radius:1.5px 1.5px 1.5px 1.5px;-moz-border-radius:1.5px 1.5px 1.5px 1.5px}.player .musicBox .musicPlayer .progressBar .barSlide{position:absolute;width:10px;height:10px;border-radius:5px 5px 5px 5px;-webkit-border-radius:5px 5px 5px 5px;-moz-border-radius:5px 5px 5px 5px;left:90px;top:-3.5px;background:linear-gradient(to right,#438aff,#fff,#438aff);cursor:pointer}.player .extensions{width:70%;height:100%;visibility:hidden;box-shadow:1px 1px 10px #fff;-webkit-box-shadow:1px 1px 10px #fff;-moz-box-shadow:1px 1px 10px #fff;-o-box-shadow:1px 1px 10px #fff;font:50px '华文楷体';text-align:center;line-height:200px}body{background:url(../resource/images/bg10.png) fixed no-repeat;background-size:100% 100%}

js

  1 $(function(){
  2     /*展开拓展栏按钮功能函数*/
  3     $('.icon.unfold').click(function(){
  4         $(this).css("display","none");//展开按钮点击后隐藏
  5         let oExt=$('.extensions');
  6         dorseyAn.unfold(oExt,"translate3d(-80%,-70%,0)","0.5s");//调用dorseyAn的动画弹出函数
  7     });
  8     /*导航栏功能函数*/
  9     $('.nav li').click(function(){
 10         $(this).find('.icon').css("color","white").siblings().find('.icon');
 11         $(this).siblings().find('.icon').css("color","");
 12         $(".nav_detail").children('div').eq($(this).index()).addClass('on').siblings().removeClass('on');
 13     });
 14     /**
 15      * 播放模块功能:这些函数暂时比较杂,后面等功能完善了会一一封装,也会优雅一些
 16      *     包括上下首歌曲切换,播放与暂停,播放进度及播放的歌曲简介如歌手歌名等等,这里先这样,后续音乐列表那还会
 17      * 做一个头像,并在播放时旋转。
 18      * */
 19 
 20     /**基本功能定义的变量,一个个定义的话也是可以的,不过呢,这样泄露太多全局变量,起码在我们这里是全局变量,咱用
 21      * 个全局对象接口包一下,也方便统一管理与后期维护
 22     * */
 23     let msBasic={
 24         $play:$('.icon.play'), //播放按钮
 25         $pause:$('.icon.pause'),//暂停按钮
 26         $audio:$('.audio'),//html5标签<audio></audio>,这里注意是jquery选出来的,是一个对象
 27         $next:$('.icon.next'),//下一首
 28         $pre:$('.icon.pre'),//上一首
 29 
 30         $barBg:$('.progressBar .barBg'),//进度条背景色标签对象
 31         $barFg:$('.progressBar .barFg'),//进度条前景色标签对象
 32         $barSlide:$('.progressBar .barSlide'),//进度条滑块标签对象
 33         $progressTime:$('.progressBar .time'),//播放进度及正在播放的歌曲简介信息(歌手,歌名等等)
 34         $dragAble:false //用于判断拖拽的滑块是否按下
 35     };
 36     let flag=0;
 37     let musicTi=['贾青 - 痴情冢','胡歌 - 月光 (TV版)','胡歌、白冰 - 美丽的神话'];
 38     //musicTi:歌名文件(存储你所有的歌曲),需要后台提供一个存储歌名的json,为方便测试,暂用字符串代替
 39     let play=function(){
 40         msBasic.$play.hide();
 41         msBasic.$pause.show();
 42         msBasic.$audio.get(0).play();
 43     };
 44     let pause=function(){
 45         msBasic.$pause.hide();
 46         msBasic.$play.show();
 47         msBasic.$audio.get(0).pause();
 48     };
 49     /*播放按钮*/
 50     msBasic.$play.click(function(){
 51         play();
 52     });
 53     /*暂停按钮*/
 54     msBasic.$pause.click(function(){
 55         pause();
 56     });
 57     let next=function(){
 58         flag++;
 59         flag%=musicTi.length;
 60         msBasic.$audio.attr("src","../resource/av/"+musicTi[flag]+".mp3");
 61         msBasic.$progressTime.children('span').eq(0).html(musicTi[flag]);
 62         play();
 63     };
 64     let previous=function(){
 65         flag--;
 66         flag<0?flag=musicTi.length-1:flag;
 67         msBasic.$audio.attr("src","../resource/av/"+musicTi[flag]+".mp3");
 68         msBasic.$progressTime.children('span').eq(0).html(musicTi[flag]);
 69         play();
 70     };
 71     /*下一首歌曲按钮*/
 72     msBasic.$next.click(function(){
 73         next();
 74     });
 75     /*上一首歌曲按钮*/
 76     msBasic.$pre.click(function(){
 77         previous();
 78     });
 79     /*监听歌曲时间变化,当然用js的addEventListener也可以*/
 80     msBasic.$audio.on("timeupdate",function(){
 81         var min,sec,minAll="00",secAll="00";
 82         /*歌曲当前播放进度*/
 83         min=dorseyHf.timeHandle(this.currentTime,"minute");//调用dorseyHf的时间处理函数,算是比较简单的封装吧
 84         sec=dorseyHf.timeHandle(this.currentTime,"second");
 85         /*歌曲播放总时长*/
 86         if(this.duration){
 87             //为什么用if呢?你可以去掉试试,因为当我们切换上下首时,duration监听不到,是一个undefined,会使计算的结果变成NaN,
 88             // 这样我们的界面也会看到这个NaN(计算的结果非数字值),这样就不好了
 89             minAll=dorseyHf.timeHandle(this.duration,"minute");
 90             secAll=dorseyHf.timeHandle(this.duration,"second");
 91         }
 92         /*播放进度条*/
 93         var allW=msBasic.$barBg.outerWidth(),slideW;
 94         slideW=allW*this.currentTime/this.duration;//当前播放进度时间除以总歌曲持续时间
 95         msBasic.$barFg.css("width",slideW+"px");
 96         msBasic.$barSlide.css("left",slideW+"px");
 97         msBasic.$progressTime.children('span').eq(1).html(min+":"+sec+"/"+minAll+":"+secAll);
 98         //播放完毕自动播放下一首
 99         if(this.currentTime>=this.duration-1){
100             //想想为什么要这样?而不是简单的currentTime等于duration就可以了?
101             next();
102         }
103     });
104     /*监听鼠标拖拽*/
105     msBasic.$barSlide.on("mousedown",function(e){
106         e=e||window.event;
107         msBasic.$slideAble=true;
108         var ex=e.pageX-msBasic.$barSlide.get(0).offsetLeft;
109         //每一次点击都存储一个滑块x初值,由于这里滑块得保持水平,所以不加一个Y,
110         // 这里各位可以延伸写一个拖拽组件出来
111         $(document).on({
112             mousemove:function(e){
113                 e=e||window.event;
114                 if(msBasic.$slideAble){
115                     var l=e.pageX-ex; //你会不会有疑问,l=e.pageX-ex=e.pageX-(e.pageX-其它)=其它?呵呵,两个是不一样的哈!
116                     //L的值,其实呢很简单,初中数学的x1-x2,只不过我们需要再考虑个原本滑块到浏览器边缘的距离
117                     l>msBasic.$barBg.width()-1?l=msBasic.$barBg.width()-1:l; //判断拖拽条是否超界
118                     l<0?l=0:l;
119                     msBasic.$audio.get(0).currentTime=(l/msBasic.$barBg.width())*msBasic.$audio.get(0).duration;
120                     msBasic.$barFg.css("width",l+"px");
121                     msBasic.$barSlide.css("left",l+"px");
122                 }
123             },
124             mouseup:function(){
125                 msBasic.$slideAble=false;
126             }
127         });
128     });
129 });

     
 虽说这里仅仅唯有多少个模块,不过呢,其实3个差不离的音乐播放器就出去了(虽说纯底层语言做,但实在算上讲授130行的代码也足以承受,当然还足以更低,临时先那样),当然,大家的卓越不唯有是这么,对吧!

 

 

 

 

 

 

最终,必要引进的五个js库文件

1、dorseyAn:动画

 1 ;(function(win){ //前面这分号别去掉哦,防止多个js文件合并压缩时因上一个js文件末尾少";"而带来的问题。
 2 
 3     "use strict"; //严格模式,一般写自己类库的时候最好加上,减少一些代码不规范引起的错误。
 4 
 5     /*模块说明:dorseyAn作为一切处理函数的入口*/
 6     let dorseyAn=function(){
 7         return new dorseyAn.fn.init();
 8     };
 9     dorseyAn.fn=dorseyAn.prototype={
10         constructor:dorseyAn, //接口名:是dorsey-animate的缩写。意为动画
11         init:function(){
12             return this;
13         },
14         unfold:function(obj,animate,time){ //2018-01封装(初级)动画展开函数,支持动画自定义,如展开方式,展开过程持续时间
15             if(obj.css("visibility")==="hidden"){
16                 obj.css("visibility","visible");
17                 obj.css("transform",animate+" scale(0)");
18                 obj.css("transform");
19                 obj.css("transition",time);
20                 obj.css("transform","");
21             }
22             obj.css("transform","");
23         },
24     };
25     dorseyAn=dorseyAn.fn.init.fn=dorseyAn.fn;
26     win.dorseyAn=dorseyAn;
27 })(window);

 二、dorseyHf:函数管理

 1 ;(function(win){ //前面这分号别去掉哦,防止多个js文件合并压缩时因上一个js文件末尾少";"而带来的问题。
 2 
 3     "use strict"; //严格模式,一般写自己类库的时候最好加上,减少一些代码不规范引起的错误。
 4 
 5     /*模块说明:dorseyHf作为一切处理函数的入口*/
 6     let dorseyHf=function(){
 7         return new dorseyHf.fn.init();
 8     };
 9     dorseyHf.fn=dorseyHf.prototype={
10         constructor:dorseyHf, //接口名:是dorsey-handle-function的缩写。意为函数处理
11         init:function(){
12             return this;
13         },
14         math:{//数学相关处理函数,注意需要通过接口dorseyHf来调用,如dorseyHf.math.random(100,200);
15             random:function(min,max){//生成一个指定范围大小的随机数,默认值小数点后15位
16                 return Math.random()*(max-min)+min;
17             },
18             randomAccuracy:function(min,max,dec){ //生成一个可以任意指定精度的随机数
19                 return Math.round((Math.random()*(max-min)+min)*Math.pow(10,dec))/Math.pow(10,dec);
20             }
21         },
22         //2018-05-25封装(初级):用于dorsey音乐播放器音乐盒上的一些时间显示处理,注意传入的参数是以秒为单位
23         timeHandle:function(times,flag){//这种方式还是不太好,暂时先这样
24             var time;
25             flag==="minute"?time=parseInt(times/60)%60:(flag==="second"?time=parseInt(times%60):
26                 (flag==="hour"?time=parseInt(times/3600)%24:null));
27             time<10?time="0"+time:time;
28             return time;
29         },
30         timeHandle1:function(times){
31         },
32         dc_ajax_g:function(url,fnSucceed,preObj,fnFail){//ajax获取操作
33             /**
34              * url:可以是后台接口,json数据,也可以是json文件位置
35              * fnSucceed:ajax获取成功后的操作
36              * preObj:预加载,ajax由于要与后台服务器做交互,这需要时间,特别是前后交互数据较大时,用于提醒用户
37              *         现在在做加载,请稍后...一般是一个gif,或者干脆一个请稍后都行,注意的是基于JQuery的$(select)对象。
38              * fnFail:ajax获取失败后返回的操作,一般类似于404这样的东西。
39              * */
40             preObj.css("display","block");
41             setTimeout(function(){
42                 var oAjax = new XMLHttpRequest();
43                 oAjax.open('GET',url,true);
44                 oAjax.send();
45                 oAjax.onreadystatechange=function(){
46                     if(oAjax.readyState==4){
47                         if(oAjax.status==200){
48                             fnSucceed(oAjax.responseText);//获取响应
49                             preObj.css("display","none");
50                         }
51                         else{
52                             if(fnFail){
53                                 fnFail(oAjax.status);
54                             }
55                         }
56                     }
57                 };
58             },1500);//这个延迟最好改为0,或者干脆把setTimeout去掉,这样加的原因是方便那些ajax获取过快的
59             // 用户可以查看到这个预加载的效果。
60         }
61     };
62     dorseyHf=dorseyHf.fn.init.fn=dorseyHf.fn;
63     win.dorseyHf=dorseyHf;
64 })(window);

 

 

 

 

持续种种模块写好了会逐年更新,等品种最终截至了会挂载到github,各位到时可自行下载。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website