AI智能
改变未来

从零玩转jQuery之项目开发(QQ音乐播放器)


QQ音乐播放器项目

大体效果如下:

HTML结构分析:

一、页面布局

1、首先来看下HTML大体结构:

<div class=\"header\"></div><div class=\"content\"><div class=\"content-in\"><div class=\"content-left\"></div><div class=\"content-right\"></div></div></div><div class=\"footer\"><div class=\"footer-in\"></div></div>

效果如下:

2、完成页面头部

HTML代码:

<div class=\"header\"><!-- logo --><h1 class=\"logo\"><a href=\"#\"></a></h1><!-- 登录注册按钮 --><ul class=\"register\"><li>登录</li><li>注册</li></ul></div>

css样式代码:

.header {width: 100%;height: 45px;}.header .logo {float: left;margin-left: 20px;opacity: .5;}.header .logo:hover {opacity: 1;}.header .logo a {display: inline-block;width: 78px;height: 21px;background: url(../images/player_logo.png) no-repeat 0 0;}.header .register {line-height: 45px;list-style: none;float: right;}.header .register li {float: left;cursor: pointer;margin-right: 20px;color: #fff;opacity: .5;}.header .register li:hover {opacity: 1;}

效果如下:

3、完成内容区的菜单部分


HTML结构如下:

<!-- 作为菜单标签 --><div class=\"content-toolbar\"><!-- 作为每个菜单按钮 --><span><i></i>收藏</span><span><i></i>添加到</span><span><i></i>下载</span><span><i></i>删除</span><span><i></i>清空列表</span></div>

css样式如下:

.content .content-in .content-left .content-toolbar {width: 100%;height: 40px;}.content .content-in .content-left .content-toolbar span {display: inline-block;width: 122px;height: 100%;border: 1px solid #fff;box-sizing: border-box;text-align: center;line-height: 40px;border-radius: 5px;opacity: .5;color: #fff;font-size: 14px;}.content .content-in .content-left .content-toolbar span:hover {opacity: 1;}.content .content-in .content-left .content-toolbar span i {width: 18px;height: 18px;display: inline-block;background: url(../images/icon_sprite.png) no-repeat 0 0;vertical-align: -5px;margin-right: 9px;}.content .content-in .content-left .content-toolbar span:nth-child(1) i {background-position: -60px -20px;}.content .content-in .content-left .content-toolbar span:nth-child(2) i {background-position: -20px -20px;}.content .content-in .content-left .content-toolbar span:nth-child(3) i {background-position: -40px -240px;}.content .content-in .content-left .content-toolbar span:nth-child(4) i {background-position: -100px -20px;}.content .content-in .content-left .content-toolbar span:nth-child(5) i {background-position: -40px -300px;}

4、完成歌曲列表布局

我们只完成第一行,因为除了第一行以外,其他的都是歌曲,后边通过js来动态创建

<!-- 作为歌曲菜单 --><div class=\"content-list\" data-mcs-theme=\"minimal-dark\"><ul><!-- 歌曲的第一行 --><li class=\"list-title\"><!-- 歌曲选中框 --><div class=\"list-check\"><i></i></div><!-- 歌曲排号 --><div class=\"list-number\"></div><!-- 歌曲名 --><div class=\"list-name\">歌曲</div><!-- 歌手 --><div class=\"list-singer\">歌手</div><!-- 歌曲时长 --><div class=\"list-time\">时长</div></li></ul></div>

css样式如下:

.content .content-in .content-left .content-list {width: 100%;/* height: 760px; */height: 600px;overflow: auto;margin-top: 50px;}.content-list li {width: 775px;height: 50px;list-style: none;border-bottom: 1px solid rgba(255, 255, 255, .5);user-select: none;}.content-list div {float: left;line-height: 50px;/*opacity: .8;*/color: rgba(255, 255, 255, .5);}.content-list .list-check {width: 50px;height: 100%;text-align: center;}.content-list .list-check i {display: inline-block;width: 14px;height: 14px;border: 1px solid #fff;box-sizing: border-box;opacity: .5;}.content-list .list-checked i {background: url(../images/icon_sprite.png) no-repeat -60px -80px;opacity: 1;}.content-list .list-number {width: 20px;height: 100%;}.content-list .list-number2 {color: transparent !important;background: url(\"../images/wave.gif\") no-repeat 0 center;}.content-list .list-name {width: 50%;height: 100%;}.content-list .list-music .list-name .list-menu {float: right;margin-top: 7px;margin-right: 10px;display: none;}.content-list .list-music .list-name .list-menu a {display: inline-block;width: 36px;height: 36px;background: url(../images/icon_list_menu.png) no-repeat 0 0;opacity: .5;}.content-list .list-music .list-name .list-menu a:hover {opacity: 1;}.content-list .list-music .list-name .list-menu a:nth-child(1) {background-position: -120px 0;}.content-list .list-music .list-name .list-menu a:nth-child(2) {background-position: -120px -80px;}.content-list .list-music .list-name .list-menu a:nth-child(3) {background-position: -120px -120px;}.content-list .list-music .list-name .list-menu a:nth-child(4) {background-position: -120px -40px;}.content-list .list-menu-play2 {background-position: -80px -200px !important;}.content-list .list-singer {width: 20%;height: 100%;}.content-list .list-time {width: 20%;height: 100%;}.content-list .list-music .list-time a {display: inline-block;width: 36px;height: 36px;background: url(../images/icon_list_menu.png) no-repeat 0 0;background-position: -120px -160px;float: left;margin-top: 7px;display: none;opacity: .5;}.content-list .list-music .list-time a:hover {opacity: 1;}

5、自定义歌曲列表滚动条

  1. 首先下载一个jQuery插件:jQuery custom content scroller(http://manos.malihu.gr/jquery-custom-content-scroller/)
  2. 引入下载好的css文件
  3. 为需要添加的元素调用mCustomScrollbar()方法:
    $(\".content_list\").mCustomScrollbar();
  4. 为该元素添加自定义属性 data-mcs-theme=“dark”:
    <div class=\"content_list\" data-mcs-theme=\'minimal-dark\'></div>
  5. 可以设置滚动条的宽度:
    ._mCS_1 .mCSB_scrollTools .mCSB_dragger_bar { width: 8px; }

如图所示自定义滚动条设置完毕:

6、右边的歌曲信息与歌词布局


HTML结构如下:

<!-- 作为内容区的右边部分 --><div class=\"content-right\"><!-- 歌手信息 --><div class=\"song-info\"><!-- 歌手图片 --><a href=\"javascript:;\" class=\"song-info-pic\"><img src=\"images/lnj.jpg\" alt=\"\"></a><!-- 歌手信息详细 --><div class=\"song-info-name\">歌曲名称:<a href=\"javascript:;\">海市蜃楼</a></div><div class=\"song-info-singer\">歌手名:<a href=\"javascript:;\">网络未知名歌手</a></div><div class=\"song-info-album\">专辑名:<a href=\"javascript:;\">未知名系列</a></div></div><div class=\"song-lyric-container\"><!-- 歌词 --><ul class=\"song-lyric\"><!-- 默认显示两条歌词 --></ul></div></div>

css样式如下:

.content-right {width: 400px;height: 100%;float: right;user-select: none;}.content-right .song-info {text-align: center;color: rgba(255, 255, 255, .5);line-height: 30px;cursor: pointer;}.content-right .song-info .song-info-pic {display: inline-block;width: 201px;height: 180px;text-align: left;background: url(../images/album_cover_player.png) no-repeat 0 0;}.song-info-pic img {width: 180px;height: 180px;}.content-right .song-info div a {text-decoration: none;color: #fff;opacity: .5;}.content-right .song-info div a:hover {opacity: 1;}.content-right .song-lyric-container {height: 300px;overflow: hidden;margin-top: 70px;/* background-color: rebeccapurple; */}.content-right .song-lyric {cursor: pointer;opacity: .7;list-style: none;text-align: center;line-height: 30px;/* font-weight: bold; */font-family: poppin,Tahoma,Arial,\\5FAE\\8F6F\\96C5\\9ED1,sans-serif;font-size: 15px;}.content-right .song-lyric .cur {color: #31c27c;}

7、底部播放按钮部分

HTML结构:

<div class=\"footer-in\"><!-- 向左播放按钮 --><a href=\"javascript:;\" class=\"music-pre\"></a><!-- 开始暂停按钮 --><a href=\"javascript:;\" class=\"music-play\"></a><!-- 向右播放按钮 --><a href=\"javascript:;\" class=\"music-next\"></a><!-- 歌曲进度条 --><div class=\"music-progress-info\"><!-- 歌曲进度条文本内容 --><div class=\"music-progress-top\"><span class=\"music-progress-name\">旧梦一场 - 阿悠悠</span><span class=\"music-progress-time\">00:00 / 05:30</span></div><!-- 歌曲进度条 --><div class=\"music-progress-bar\"><div class=\"music-progress-line\"><div class=\"music-progress-dot\"></div></div></div></div><!-- 模式按钮 --><a href=\"javascript:;\" class=\"music-mode\"></a><!-- 收藏按钮 --><a href=\"javascript:;\" class=\"music-fav\"></a><!-- 下载按钮 --><a href=\"javascript:;\" class=\"music-down\"></a><!-- 评论按钮 --><a href=\"javascript:;\" class=\"music-comment\"></a><!-- 纯净模式按钮 --><a href=\"javascript:;\" class=\"music-only \"></a><!-- 音量按钮 --><div class=\"music-voice-info\"><!-- 音量图标 --><a href=\"javascript:;\" class=\"music-voice-icon\"></a><!-- 作为右浮的容器 --><div class=\"music-voice-right\"><!-- 音量进度条 --><div class=\"music-voice-bar\"><div class=\"music-voice-line\"><div class=\"music-voice-dot\"></div></div></div></div></div></div>

css样式:

.footer {width: 100%;height: 80px;position: absolute;bottom: 0;}.footer-in {width: 1200px;height: 100%;margin: auto;user-select: none;}.footer-in div {display: inline-block;}.footer-in a {display: inline-block;text-decoration: none;background: url(../images/player.png) no-repeat 0 0;margin-right: 40px;}.footer-in .music-pre {width: 19px;height: 20px;background-position: 0 -30px}.footer-in .music-play {width: 21px;height: 29px;background-position: 0 0;vertical-align: -5px;}.footer-in .music-play2 {background-position: -30px 0;}.footer-in .music-next {width: 19px;height: 20px;background-position: 0 -52px;}.footer-in .music-progress-info {width: 500px;height: 40px;margin-right: 40px;}.footer-in .music-progress-info .music-progress-top {width: 100%;height: 20px;line-height: 20px;color: #fff;}.footer-in .music-progress-info .music-progress-top .music-progress-name {float: left;}.footer-in .music-progress-info .music-progress-top .music-progress-time {float: right;}.footer-in .music-progress-info .music-progress-bar {width: 100%;height: 4px;background-color: rgba(255, 255, 255, .5);position: relative;}.footer-in .music-progress-info .music-progress-line {width: 0;height: 100%;background-color: #fff;float: left;}.footer-in .music-progress-info .music-progress-dot {width: 14px;height: 14px;border-radius: 50%;background-color: white;position: absolute;top: -5px;left: 0;}.footer-in .music-mode {width: 26px;height: 25px;background-position: 0 -205px;}.footer-in .music-mode2 {width: 23px;height: 20px;background-position: 0 -260px;}.footer-in .music-mode3 {width: 25px;height: 19px;background-position: 0 -74px;}.footer-in .music-mode4 {width: 26px;height: 25px;background-position: 0 -232px;}.footer-in .music-fav {width: 24px;height: 21px;background-position: 0 -96px;}.footer-in .music-fav2 {background-position: -30px -96px;}.footer-in .music-down {width: 22px;height: 21px;background-position: 0 -120px;}.footer-in .music-comment {width: 24px;height: 24px;background-position: 0 -400px;}.footer-in .music-only {width: 74px;height: 27px;background-position: 0 -281px;margin-right: 20px;}.footer-in .music-only2 {background-position: 0 -310px;}.footer-in .music-voice-info {width: 93px;height: 24px;}.footer-in .music-voice-info .music-voice-icon {display: inline-block;width: 26px;height: 21px;background-position: 0 -144px;margin-right: 0;}.footer-in .music-voice-info .music-voice-icon2{background-position: 0 -182px;}.footer-in .music-voice-info .music-voice-right {width: 68%;height: 100%;float: right;margin-right: 0;margin-top: -3px;}.footer-in .music-voice-info .music-voice-bar {width: 100%;height: 4px;background-color: rgba(255, 255, 255, .5);}.footer-in .music-voice-info .music-voice-line {width: 100%;height: 100%;background-color: #fff;position: relative;float: left;}.footer-in .music-voice-info .music-voice-dot {width: 14px;height: 14px;border-radius: 50%;background-color: white;position: absolute;top: -5px;left: 100%;}

8、高斯模糊背景设置

我们需要定义两div用来设置页面整体高斯模糊背景图像

<!-- 歌手音乐图片作为背景效果 --><div class=\"mask-bg\"></div><!-- 灰色遮罩 --><div class=\"mask\"></div>

有了这两元素大体上就可以设置我们的背景效果了。
css样式效果如下:

.mask-bg {z-index: -2;width: 100%;height: 100%;background: url(../images/lnj.jpg) no-repeat 0 0;background-size: cover;position: absolute;top: 0;left: 0;filter: blur(100px);/* 图片模糊设置 */}.mask {width: 100%;height: 100%;position: absolute;top: 0;left: 0;background: rgba(0, 0, 0, 0.35);z-index: -1;}

注意点:

z-index 属性指定一个元素的堆叠顺序。
拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。

到现在为止,静态页面已经布局完毕。

二、页面动态部分

为了后期的维护,我们需要单独为每个类型功能封装到一个js文件中。

其中QQ音乐的关于播放的功能都封装到了player.js的文件中,进度条的功能都封装到了progress.js中,关于歌词的显示部分封装到了lyric.js 中,其他逻辑部分封装到index.js中。

1、index.js

$(function () {// 0.自定义滚动条$(\".content-list\").mCustomScrollbar();var $audio = $(\"audio\");var player = new Player($audio);var progress, voiceProgressvar lyric//加载歌曲列表getPlayerList();function getPlayerList() {// 解析json文件$.ajax({url: \"./source/musiclist.json\",dataType: \"json\",success: function (data) {player.musicList = data// 3.1遍历获取到的数据,创建每一条音乐var $musicList = $(\".content-list ul\");$.each(data, function (index, ele) {// 调用创建音乐函数var $item = crateMusicItem(index, ele);$musicList.append($item)})// 调用歌曲信息函数initMusicInfo(data[0])// 调用歌词信息函数initMusicLyric(data[0])},error: function (e) {console.log(e)}})}//初始化歌曲信息function initMusicInfo(music) {// 获取元素var $musicImage = $(\'.song-info-pic img\')var $musicName = $(\'.song-info-name a\')var $musicSinger = $(\'.song-info-singer a\')var $musicAlbum = $(\'.song-info-album a\')var $musicProgressName = $(\'.music-progress-name\')var $musicProgressTime = $(\'.music-progress-time\')var $musicBg = $(\'.mask-bg\')// 给获取到的元素赋值$musicImage.attr(\'src\', music.cover)$musicName.text(music.name)$musicSinger.text(music.singer)$musicAlbum.text(music.album)$musicProgressName.text(music.name + \' / \' + music.singer)$musicProgressTime.text(\'00:00 / \' + music.time)$musicBg.css(\"background\",\"url(\'\"+music.cover+\"\')\")}//初始化歌词信息function initMusicLyric(music) {lyric = new Lyric(music.link_lrc)var $lyricContainer = $(\'.song-lyric\')// 清空上一首音乐歌词$lyricContainer.html(\'\')lyric.loadLyric(function () {// 创建歌词列表$.each(lyric.lyrics, function (index,ele) {var $item = $(\"<li>\" + ele + \"</li>\")$lyricContainer.append($item)})})}//初始化进度条initProgress()function initProgress() {var $progressBar = $(\".music-progress-bar\")var $progressLine = $(\".music-progress-line\")var $progressDot = $(\".music-progress-dot\")progress = Progress($progressBar, $progressLine, $progressDot)progress.progressClick(function (value) {player.musicSeekTo(value)})progress.progressMove(function (value) {player.musicSeekTo(value)})var $voiceBar = $(\".music-voice-bar\")var $voiceLine = $(\".music-voice-line\")var $voiceDot = $(\".music-voice-dot\")voiceProgress = Progress($voiceBar, $voiceLine, $voiceDot)voiceProgress.progressClick(function (value) {player.musicVoiceSeekTo(value)})voiceProgress.progressMove(function (value) {player.musicVoiceSeekTo(value)})}//初始化事件监听initEvents()function initEvents() {// 1.监听歌曲的移入移出事件$(\".content-list\").delegate(\".list-music\", \"mouseenter\", function () {// 显示子菜单$(this).find(\'.list-menu\').stop().fadeIn(100)$(this).find(\'.list-time a\').stop().fadeIn(100)//隐藏时长$(this).find(\'.list-time span\').stop().fadeOut(100)})$(\".content-list\").delegate(\".list-music\", \"mouseleave\", function () {// 隐藏子菜单$(this).find(\'.list-menu\').stop().fadeOut(100)$(this).find(\'.list-time a\').stop().fadeOut(100)//显示时长$(this).find(\'.list-time span\').stop().fadeIn(100)})// 2.监听复选框的点击事件$(\".content-list\").delegate(\".list-check\", \"click\", function () {$(this).toggleClass(\"list-checked\")})// 3.添加子菜单播放按钮的监听var $musicPlay = $(\".music-play\")$(\".content-list\").delegate(\".list-menu-play\", \"click\", function () {var $item = $(this).parents(\".list-music\")// 3.1切换播放图图标$(this).toggleClass(\"list-menu-play2\")// 3.2.复原其他的播放图标$item.siblings().find(\".list-menu-play\").removeClass(\"list-menu-play2\")// 3.3同步底部播放按钮if ($(this).attr(\"class\").indexOf(\"list-menu-play2\") != -1) {//当前子菜单的播放按钮是播放状态$musicPlay.addClass(\"music-play2\")//让文字高亮$item.find(\"div\").css(\"color\", \"#fff\")$item.siblings().find(\"div\").css(\"color\", \"rgba(255,255,255,0.5)\")} else {// 当前子菜单的播放按钮不是播放状态$musicPlay.removeClass(\"music-play2\")//让文字不高亮$item.find(\"div\").css(\"color\", \"rgba(255,255,255,0.5)\")}// 3.4切换序号的状态$item.find(\".list-number\").toggleClass(\"list-number2\")$item.siblings().find(\".list-number\").removeClass(\"list-number2\")// 3.5播放音乐player.playMusic($item.get(0).index, $item.get(0).music)// 3.6切换歌曲信息initMusicInfo($item.get(0).music)// 3.7切换歌词的信息initMusicLyric($item.get(0).music)})// 4、监听底部控制区域播放按钮点击$musicPlay.click(function () {// 判断是否播放过音乐if (player.currentIndex == -1) {// 没有播放过$(\'.list-music\').eq(0).find(\'.list-menu-play\').trigger(\'click\')} else {// 播放过$(\'.list-music\').eq(player.currentIndex).find(\'.list-menu-play\').trigger(\'click\')}})// 5、监听底部控制区域上一首播放按钮点击$(\".music-pre\").click(function () {$(\'.list-music\').eq(player.preIndex()).find(\'.list-menu-play\').trigger(\'click\')})// 6、监听底部控制区域下一首播放按钮点击$(\".music-next\").click(function () {$(\'.list-music\').eq(player.nextIndex()).find(\'.list-menu-play\').trigger(\'click\')})// 7、监听删除按钮的点击$(\'.content-list\').delegate(\'.list-menu-del\', \'click\', function () {// 找到被点击的按钮var $item = $(this).parents(\'.list-music\')// 判断当前删除的是否是已经播放的if ($item.get(0).index == player.currentIndex) {$(\".music-next\").trigger(\'click\')}$item.remove()player.changeMusic($item.get(0).index)// 重新排序$(\'.list-music\').each(function (index,ele) {ele.index = index$(ele).find(\'.list-number\').text(index + 1)})})// 8、监听播放的进度player.musicTimeUpdate(function (currentTime, duration, timeStr) {// 同步时间$(\'.music-progress-time\').text(timeStr)// 同步进度条// 计算播放比例var value = currentTime / duration * 100progress.setProgress(value)// 实现歌词同步var index = lyric.currentIndex(currentTime)var $item = $(\".song-lyric li\").eq(index)$item.addClass(\'cur\')$item.siblings().removeClass(\'cur\')if (index <= 2) return;$(\".song-lyric\").css({marginTop : ((-index +4) * 30)})})// 9、监听声音按钮点击$(\'.music-voice-icon\').click(function () {// 图表切换$(this).toggleClass(\'music-voice-icon2\')// 声音切换if ($(this).attr(\'class\').indexOf(\'music-voice-icon2\') != -1) {// 没有声音player.musicVoiceSeekTo(0)} else {// 有声音player.musicVoiceSeekTo(1)}})// 10、监听模式按钮的点击$(\'.music-mode\').click(function () {// 模式切换$(this).toggleClass(\'music-mode2\')$(this).toggleClass(\'music-mode3\')// $(this).toggleClass(\'music-mode4\')})// 11、监听纯净模式的点击$(\'.music-only\').click(function () {// 按钮切换$(this).toggleClass(\'music-only2\')})}// 定义一个方法创建一条音乐function crateMusicItem(index, music) {var $item = $(\"\" +\"<li class=\\\"list-music\\\">\\n\" +\"<div class=\\\"list-check\\\"><i></i></div>\\n\" +\"<div class=\\\"list-number\\\">\" + (index + 1) + \"</div>\\n\" +\"<div class=\\\"list-name\\\">\" + music.name + \"\" +\"     <div class=\\\"list-menu\\\">\\n\" +\"          <a href=\\\"javascript:;\\\" title=\\\"播放\\\" class=\'list-menu-play\'></a>\\n\" +\"          <a href=\\\"javascript:;\\\" title=\\\"添加\\\"></a>\\n\" +\"          <a href=\\\"javascript:;\\\" title=\\\"下载\\\"></a>\\n\" +\"          <a href=\\\"javascript:;\\\" title=\\\"分享\\\"></a>\\n\" +\"     </div>\\n\" +\"</div>\\n\" +\"<div class=\\\"list-singer\\\">\" + music.singer + \"</div>\\n\" +\"<div class=\\\"list-time\\\">\\n\" +\"     <span>\" + music.time + \"</span>\\n\" +\"     <a href=\\\"javascript:;\\\" title=\\\"删除\\\" class=\'list-menu-del\'></a>\\n\" +\"</div>\\n\" +\"</li>\");$item.get(0).index = index$item.get(0).music = musicreturn $item}})

2、player.js

(function (window) {function Player($audio) {return new Player.prototype.init($audio);}Player.prototype = {constructor: Player,musicList: [],init: function ($audio) {this.$audio = $audio;this.audio = $audio.get(0);},currentIndex: -1, // 4  3playMusic: function (index, music) {// 判断是否是同一首音乐if (this.currentIndex == index) {// 同一首音乐if (this.audio.paused) {this.audio.play();} else {this.audio.pause();}} else {// 不是同一首this.$audio.attr(\"src\", music.link_url);this.audio.play();this.currentIndex = index;}},// 处理播放索引为负数的情况preIndex: function () {var index = this.currentIndex - 1;if (index < 0) {index = this.musicList.length - 1;}return index;},// 处理播放索引大于歌曲索引长度的情况nextIndex: function () {var index = this.currentIndex + 1;if (index > this.musicList.length - 1) {index = 0;}return index;},changeMusic: function (index) {// 删除对应的数据this.musicList.splice(index, 1)// 判断当前删除的是否是正在播放的音乐的前面的if (index < this.currentIndex) {this.currentIndex = this.currentIndex -1}},// 封装一个更新音乐时间的方法musicTimeUpdate: function (callBack) {var $this = thisthis.$audio.on(\'timeupdate\', function () {// console.log(player.getMusicDuration(), player.getMusicCurrentTime())var duration = $this.audio.durationvar currentTime = $this.audio.currentTimevar timeStr = $this.formatDate(currentTime, duration)callBack(currentTime, duration, timeStr)})},formatDate: function (currentTime, duration) {var endMin = parseInt(duration / 60)var endSec = parseInt(duration % 60)if (endMin < 10) {endMin = \"0\" + endMin}if (endSec < 10) {endSec = \"0\" + endSec}var startMin = parseInt(currentTime / 60)var startSec = parseInt(currentTime % 60)if (startMin < 10) {startMin = \"0\" + startMin}if (startSec < 10) {startSec = \"0\" + startSec}return startMin + \":\" + startSec + \" / \" + endMin + \":\" + endSec},musicSeekTo: function (value) {if (isNaN(value)) return;this.audio.currentTime = this.audio.duration * value;},musicVoiceSeekTo: function (value) {if (isNaN(value)) return;if (value < 0 || value > 1) return;this.audio.volume = value}}Player.prototype.init.prototype = Player.prototype;window.Player = Player;})(window);

3、progress.js

// 操作进度条(function (window) {function Progress($progressBar, $progressLine, $progressDot) {return new Progress.prototype.init($progressBar, $progressLine, $progressDot);}Progress.prototype = {constructor: Progress,init: function ($progressBar, $progressLine, $progressDot) {this.$progressBar = $progressBarthis.$progressLine = $progressLinethis.$progressDot = $progressDot},isMove : false,// 进度条前景的点击方法progressClick: function (callBack) {var $this = this //this是progressthis.$progressBar.click(function (event) {// 获取背景距离窗口默认位置var normalLeft = $(this).offset().left// 获取点击的位置距离窗口的位置var eventLeft = event.pageX// 设置前景的宽度$this.$progressLine.css(\'width\', eventLeft - normalLeft)$this.$progressDot.css(\'left\', eventLeft - normalLeft)// 计算进度条的比例var value = (eventLeft - normalLeft) / $(this).width()callBack(value)})},// 进度条原点的拖动方法progressMove: function (callBack) {var $this = this// 获取背景距离窗口默认位置var normalLeft = this.$progressBar.offset().leftvar eventLeftvar barWidth = this.$progressBar.width()// 1、监听鼠标的按下事件this.$progressBar.mousedown(function () {$this.isMove = true// 2、监听鼠标的拖动事件$(document).mousemove(function () {// 获取点击的位置距离窗口的位置eventLeft = event.pageX// 判断进度条的长度是否合法var offset = eventLeft - normalLeftif (offset >= 0 && offset <= barWidth) {// 设置前景的宽度$this.$progressLine.css(\'width\', eventLeft - normalLeft)$this.$progressDot.css(\'left\', eventLeft - normalLeft)}})})// 3、监听鼠标的抬起事件$(document).mouseup(function () {// 移出拖动事件$(document).off(\'mousemove\')$this.isMove = false// 计算进度条的比例var value = (eventLeft - normalLeft) / $this.$progressBar.width()callBack(value)})},setProgress: function (value) {if(this.isMove) returnif (value < 0 || value > 100) return;this.$progressLine.css({width: value + \"%\"})this.$progressDot.css({left :value + \"%\"})}}Progress.prototype.init.prototype = Progress.prototype;window.Progress = Progress;})(window);

4、lyric.js

(function (window) {function Lyric(path) {return new Lyric.prototype.init(path);}Lyric.prototype = {constructor: Lyric,init: function (path) {this.path = path},times :[],lyrics: [],index : -1,loadLyric: function (callBack) {var $this = this$.ajax({url:$this.path,dataType: \"text\",success: function (data) {$this.parseLyric(data)callBack()},error: function (e) {console.log(e)}})},parseLyric: function (data) {var $this = this// 清空歌词跟时间$this.times = []$this.lyrics = []var array = data.split(\'\\n\')// 利用正则匹配时间var timeReg = /\\[(\\d*:\\d*\\.\\d*)\\]/// 遍历$.each(array, function (index, ele) {var lrc = ele.split(\"]\")[1]// 排除空字符串if (lrc.length == 1) return true;$this.lyrics.push(lrc)var res = timeReg.exec(ele)// console.log(res)if (res == null) return true;var timeStr = res[1]var res2 = timeStr.split(\':\')var min = parseInt(res2[0]) * 60var sec = parseFloat(res2[1])var time = parseFloat(Number(min + sec).toFixed(2))// console.log(typeof time)$this.times.push(time)})// console.log($this.times)// console.log($this.lyrics)},currentIndex: function (currentTime) {// console.log(currentTime)if (currentTime >= this.times[0]) {this.index++this.times.shift()  //删除数组最前面的一个元素}return this.index}}Lyric.prototype.init.prototype = Lyric.prototype;window.Lyric = Lyric;})(window);

5、注意点

写jQuery代码你首先导入jQuery库,一个js文件。js文件的导入是有顺序的,在一个js文件中会用到其他的js文件中的方法,导入顺序必须有先后

<link rel=\"stylesheet\" href=\"css/jquery.mCustomScrollbar.css\"><link rel=\"stylesheet\" href=\"css/index.css\"><script src=\"js/jquery-1.12.4.js\"></script><script src=\"js/jquery.mCustomScrollbar.concat.min.js\"></script><script src=\"js/player.js\"></script><script src=\"js/progress.js\"></script><script src=\"js/lyric.js\"></script><script src=\"js/index.js\"></script>
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 从零玩转jQuery之项目开发(QQ音乐播放器)