本人目前准备利用闲暇时间打造一个完整的音乐播放器项目,主要用于学习及分享!原创不易,转载请注明出处。

       这是一个什么样的音乐播放器呢?整体的架构跟酷狗差不多吧,我的方式呢,是一个个组件一个个模块先做好,最后组合成完整的项目,最后项目会放在本人的github上,等项目完毕后会发布链接。另外呢,这个算是对自己曾经封装过的函数的一些检验,为了方便原理上的了解,整个项目不会用到任何的控件及插件,算是从底层的js或jq+audio开始吧(实际开发不推荐,这样效率太低,不过用于提升自己的还是推荐这样,写过一遍跟引用一遍是完全不同两个概念),当然也会适当的封一些函数,这些会放在文章的最末尾,每个模块或多或少都会引用其中部分函数。

模块①、歌词同步:(为了方便测试,先用了html5提供好的audio标签,我们只做歌词功能),初步效果是这样:(另外直接在酷狗下载歌词文件就可以用了)

       这个其实不难,不过呢,咱用点最笨的办法(关于解析字符串,不用正则匹配),酷狗都用过吧,里面的歌词文件是.krc文件,这种文件是加密过的,所以呢,从酷狗下载下来的歌词文件需要先转化成lrc文件,推荐下面的软件:

krc文件点开是这样的:

转化成lrc文件后是这样的:

注意这时候lrc文件的字符编码不是utf-8,各位需要自行另存为utf-8文件,好了,歌词文件准备好了,可以开始我们的歌词模块了。

css及js文件我全部放在html里,完善后会逐步封装,css会采用less代替。

 

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

 

 

 

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

 

 模块②、音乐盒之基本功能——播放暂停,上下首切换,歌曲详情,歌曲播放进度(可自由拖动),自动列表循环播放。

不知不觉快1点了,时间过得好快,这个项目的左侧是音乐盒,右侧是拓展,音乐盒是这样:

算上拓展功能差不多是这样:

由于本人不懂UI,配色设计不好请见谅,咱更看重的是功能实现,废话不多说了。

      初步构思的时候,整个播放器的图标还是比较多的,这里推荐一种比较好的方式——阿里字体iconfont,跟你逛淘宝一样,进入iconfont官网后,对你想要的图标各种买买买,加购物车,当然不用钱的,你再也不用担心你男朋友不帮你清空购物车了,添加完购物车后呢,这些字体呢有好几种方式提供给你,做成图标的png格式,svg格式,jpg格式等等,还有最重要的字体模式,你点下载代码就可以了。

下载完解压是这样的:

你只需根据提示(点开3个html里面任意一个看你要用什么格式,这写html可以理解成教学文档之类的),照着做就可以了。

好了,基本的素材准备好了,开始我们的代码之旅吧!

html部分:

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

css

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

       虽说这里仅仅只有两个模块,不过呢,其实一个简易的音乐播放器就出来了(虽说纯底层语言做,但其实算上注释130行的代码也可以接受,当然还可以更低,暂时先这样),当然,我们的理想不仅仅是这样,对吧!

 

 

 

 

 

 

最后,需要引入的两个js库文件

1、dorseyAn:动画

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

 2、dorseyHf:函数处理

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

 

 

 

 

后续每个模块写好了会逐步更新,等项目最终完毕了会挂载到github,各位到时可自行下载。

版权声明:本文为dorseych原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/dorseych/p/9070092.html