├── icon.png ├── README.md ├── index.html ├── style.css └── script.js /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moeshin/QPlayer/HEAD/icon.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QPlayer 2 | 3 | This project bas been deprecated in favour of [QPlayer2](https://github.com/moeshin/QPlayer2) 4 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QPlayer 6 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 32 | 33 | 34 |
35 |
36 |
37 | 38 | 39 | 40 |
41 |
42 | name - artist 43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
00:00
51 |
52 |
53 |
54 | 55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
    69 |
      70 |
      71 | 72 |
      73 | 74 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * QPlayer 3 | * 一款简洁小巧的HTML5底部悬浮音乐播放器 4 | * @author 小さな手は 5 | * @version 1.0.2 6 | * @link https://www.littlehands.site/ 7 | * @link https://github.com/moeshin/QPlayer/ 8 | */ 9 | #QPlayer ::-webkit-scrollbar { 10 | width: 3px; 11 | } 12 | #QPlayer ::-webkit-scrollbar-thumb { 13 | border-radius: 10px; 14 | background: rgba(0,0,0,0.1); 15 | -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); 16 | } 17 | #QPlayer ::-webkit-scrollbar-track { 18 | -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 19 | border-radius: 10px; 20 | } 21 | @-webkit-keyframes rotate { 22 | from { 23 | -webkit-transform:rotate(0deg) 24 | } 25 | to { 26 | -webkit-transform:rotate(360deg) 27 | } 28 | } 29 | @-moz-keyframes rotate { 30 | from { 31 | -moz-transform:rotate(0deg) 32 | } 33 | to { 34 | -moz-transform:rotate(360deg) 35 | } 36 | } 37 | @-ms-keyframes rotate { 38 | from { 39 | -ms-transform:rotate(0deg) 40 | } 41 | to { 42 | -ms-transform:rotate(360deg) 43 | } 44 | } 45 | @-o-keyframes rotate { 46 | from { 47 | -o-transform:rotate(0deg) 48 | } 49 | to { 50 | -o-transform:rotate(360deg) 51 | } 52 | } 53 | #QPlayer { 54 | z-index: 100; 55 | position: fixed; 56 | left: -250px; 57 | bottom: 50px; 58 | transition: transform .8s; 59 | pointer-events: none; 60 | } 61 | #QPlayer.pop { 62 | transform: translateX(250px); 63 | } 64 | #QPlayer .player { 65 | float: left; 66 | width: 250px; 67 | height: 60px; 68 | background: rgb(255,255,255); 69 | } 70 | #QPlayer .cover { 71 | position: absolute; 72 | width: 60px; 73 | height: 60px; 74 | } 75 | #QPlayer .cover img { 76 | width: 100%; 77 | height: 100%; 78 | border-radius: 50%; 79 | cursor: pointer; 80 | } 81 | #QPlayer .cover img.rotate { 82 | animation: rotate 10s linear 0s infinite normal none paused; 83 | } 84 | #QPlayer.playing .cover img.rotate { 85 | animation-play-state: running; 86 | } 87 | #QPlayer .ctrl { 88 | padding: 8px; 89 | margin-left: 60px; 90 | line-height: 14px; 91 | font-size: 14px; 92 | color: #636363; 93 | } 94 | #QPlayer .title { 95 | overflow: hidden; 96 | white-space:nowrap; 97 | } 98 | #QPlayer .title strong, #QPlayer .title span { 99 | display: inline; 100 | width: 80%; 101 | font-size: 85%; 102 | text-overflow: ellipsis; 103 | } 104 | #QPlayer .title span { 105 | margin-top: 5px; 106 | font-size: 12px; 107 | color: #757575; 108 | } 109 | #QPlayer .progress { 110 | height: 2px; 111 | margin: 6px 0; 112 | background: #cdcdcd; 113 | cursor: pointer; 114 | } 115 | #QPlayer .progress .already { 116 | position: relative; 117 | max-width: 100%; 118 | height: 2px; 119 | background: #e12; 120 | } 121 | #QPlayer .progress .btn { 122 | position: absolute; 123 | top: -4px; 124 | right: -4px; 125 | width: 8px; 126 | height: 8px; 127 | background-color: #FFF; 128 | border-radius: 50%; 129 | border: 1px solid #d0d0d0; 130 | } 131 | #QPlayer .timer { 132 | font-size: 12px; 133 | color: #5f5f5f; 134 | line-height: 18px; 135 | } 136 | #QPlayer .icon { 137 | background: url(icon.png) no-repeat; 138 | cursor: pointer; 139 | } 140 | #QPlayer .icon.last, #QPlayer .icon.next { 141 | position: absolute; 142 | top: 4px; 143 | width: 9px; 144 | height: 10px; 145 | } 146 | #QPlayer .icon.last { 147 | left: 0; 148 | background-position: -36px 0; 149 | } 150 | #QPlayer .icon.play { 151 | width: 14px; 152 | height: 18px; 153 | margin: 0 auto; 154 | } 155 | #QPlayer.playing .icon.play { 156 | background-position: -18px 0; 157 | } 158 | #QPlayer .icon.next { 159 | right: 0; 160 | background-position: -49px 0; 161 | } 162 | #QPlayer .contr { 163 | position: relative; 164 | } 165 | #QPlayer .contr .left { 166 | position: absolute; 167 | } 168 | #QPlayer .contr .center { 169 | position: relative; 170 | width: 72px; 171 | margin: 0 auto; 172 | } 173 | #QPlayer .contr .right { 174 | position: absolute; 175 | top: 4px; 176 | right: 0; 177 | } 178 | #QPlayer .contr .right div { 179 | float: left; 180 | margin-left: 5px; 181 | } 182 | #QPlayer .lyric-btn { 183 | width: 10px; 184 | height: 11px; 185 | background-position: -79px 0; 186 | } 187 | #QPlayer .list-btn { 188 | width: 13px; 189 | height: 11px; 190 | background-position: -62px 0; 191 | } 192 | #QPlayer .contr .icon { 193 | opacity: .8; 194 | } 195 | #QPlayer .contr .icon:hover { 196 | opacity: 1; 197 | } 198 | #QPlayer .pop-btn { 199 | float: left; 200 | width: 20px; 201 | height: 60px; 202 | background: #e12; 203 | cursor: pointer; 204 | } 205 | #QPlayer .pop-btn .icon { 206 | position: relative; 207 | top: 20px; 208 | width: 20px; 209 | height: 20px; 210 | background-position: -92px 0; 211 | -webkit-transition: all .3s ease-out; 212 | -moz-transition: all .3s ease-out; 213 | -ms-transition: all .3s ease-out; 214 | -o-transition: all .3s ease-out; 215 | transition: all .3s ease-out; 216 | } 217 | #QPlayer.pop .pop-btn .icon { 218 | transform: rotate(180deg); 219 | } 220 | #QPlayer.unselectable, #QPlayer .icon { 221 | -moz-user-select: -moz-none; 222 | -khtml-user-select: none; 223 | -webkit-user-select: none; 224 | -ms-user-select: none; 225 | user-select: none; 226 | } 227 | #QPlayer .list { 228 | float: left; 229 | width: 248px; 230 | max-height: .02px; 231 | padding: 0; 232 | margin: 0; 233 | overflow: auto; 234 | background: rgb(255,255,255); 235 | border: none; 236 | transition: max-height .8s; 237 | } 238 | #QPlayer .more.list-show .list{ 239 | max-height: 358px; 240 | border: 1px solid rgb(222, 222, 222); 241 | transform: none; 242 | } 243 | #QPlayer .list li { 244 | padding: 2px 10px; 245 | overflow: hidden; 246 | color: #989898; 247 | font-size: 11px; 248 | line-height: 2; 249 | text-overflow: ellipsis; 250 | list-style-position: inside; 251 | list-style-type: decimal; 252 | cursor: pointer; 253 | } 254 | #QPlayer .list li.error { 255 | color: rgb(221, 221, 221) !important; 256 | } 257 | #QPlayer .list li:hover, #QPlayer .list li.current { 258 | padding: 2px 10px 2px 6px; 259 | color: #716e6e; 260 | font-weight: bold; 261 | border-left: 4px solid #e12; 262 | } 263 | #QPlayer .list strong { 264 | margin-left: 5px; 265 | } 266 | #QPlayer .list span { 267 | float: right; 268 | } 269 | #QPlayer .list li, #QPlayer .contr .icon{ 270 | transition: .2s; 271 | -webkit-font-smoothing: antialiased; 272 | } 273 | #QPlayer .lyric { 274 | float: left; 275 | width: 150px; 276 | height: 0; 277 | overflow: hidden; 278 | background: rgba(255,255,255,.8); 279 | border-radius: 0 5px 5px 0; 280 | transition: height .8s; 281 | } 282 | #QPlayer .more.lyric-show .lyric { 283 | height: 160px; 284 | border: 1px solid rgb(222, 222, 222); 285 | } 286 | #QPlayer .lyric ol { 287 | height: 150px; 288 | margin: 5px; 289 | padding: 0; 290 | overflow: auto; 291 | font-size: 12px; 292 | text-align: center; 293 | } 294 | #QPlayer .lyric ol.no li { 295 | position: relative; 296 | top: 50%; 297 | margin: 0; 298 | transform: translateY(-50%); 299 | } 300 | #QPlayer .lyric li { 301 | margin: 10px 0 10px; 302 | } 303 | #QPlayer .lyric ol.no, 304 | #QPlayer .lyric li.current { 305 | color: #e12; 306 | } 307 | #QPlayer .more { 308 | float: left; 309 | transition: transform .8s; 310 | } 311 | #QPlayer .more.lyric-show, 312 | #QPlayer.pop .more.list-show.lyric-show, 313 | #QPlayer.pop .more.list-show{ 314 | transform: translateX(0); 315 | } 316 | #QPlayer .more, #QPlayer.pop .more.lyric-show { 317 | transform: translateX(-250px); 318 | } 319 | #QPlayer .body, #QPlayer .list, #QPlayer .lyric { 320 | pointer-events: auto; 321 | } -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | /** 2 | * QPlayer 3 | * 一款简洁小巧的HTML5底部悬浮音乐播放器 4 | * @package QPlayer 5 | * @author 小さな手は 6 | * @version 1.0.2 7 | * @link https://www.littlehands.site/ 8 | * @link https://github.com/moeshin/QPlayer/ 9 | */ 10 | window.QPlayer = { 11 | isAuto: false, 12 | onSetRotate: function () {} 13 | }; 14 | (function (q) { 15 | var 16 | isRandom = q.isRandom, 17 | isRotate = q.isRotate; 18 | 19 | if (isRandom === undefined) 20 | isRandom = true; 21 | 22 | if (isRotate === undefined) 23 | isRotate = true; 24 | 25 | /** 26 | * 变量监听 27 | */ 28 | Object.defineProperties(q,{ 29 | isRandom: { 30 | get: function () { 31 | return isRandom; 32 | }, 33 | set: function (bool) { 34 | isRandom = bool; 35 | q.history = [q.listIndex]; 36 | q.histIndex = 0; 37 | } 38 | }, 39 | isRotate: { 40 | get: function () { 41 | return isRotate; 42 | }, 43 | set: function (bool) { 44 | isRotate = bool; 45 | q.onSetRotate(bool); 46 | } 47 | } 48 | }); 49 | })(QPlayer); 50 | $(function () { 51 | 52 | /** 53 | * 鼠标点击进度 54 | * 55 | * @param int 56 | */ 57 | function mouseProgress(mouseX) { 58 | if (isProgressClick){ 59 | var x1 = mouseX - $progress.offset().left; 60 | x2 = $progress.width(); 61 | if (x1 <= x2) 62 | $already.width(x1); 63 | else 64 | $already.width(x2); 65 | } 66 | } 67 | 68 | /** 69 | * 秒到分钟 70 | * 71 | * @param int 72 | * @return string eg:"00:00" 73 | */ 74 | function sToMin(s) { 75 | min = parseInt(s/60); 76 | s = parseInt(s%60); 77 | if (min < 10) 78 | min = '0'+min; 79 | if (s < 10) 80 | s = '0'+s; 81 | return min+":"+s; 82 | } 83 | 84 | /** 85 | * 是否超过标签 86 | * 87 | */ 88 | function isExceedTitle() { 89 | var width = 0; 90 | $title.children().each(function () { 91 | width += $(this).width(); 92 | }); 93 | return width > $title.width(); 94 | } 95 | 96 | /** 97 | * 随机 98 | * 99 | * @return int 100 | */ 101 | function random() { 102 | if (q.list instanceof Array) { 103 | if (q.isRandom) { 104 | return Math.round(Math.random() * q.list.length-1); 105 | } 106 | return ++q.listIndex === q.list.length ? 0 : q.listIndex; 107 | } 108 | return 0; 109 | } 110 | 111 | /** 112 | * 选择歌词 113 | * 114 | * @param int 115 | */ 116 | function lyricSelect(index){ 117 | $lyricLi.removeClass('current'); 118 | var $current = $lyricLi.eq(index).addClass('current'); 119 | $lyricOl.stop(true).animate({ 120 | scrollTop: $current.offset().top-$lyricOl.offset().top+$lyricOl.scrollTop()-($lyricOl.height()-$current.height())/2 121 | }); 122 | } 123 | 124 | /** 125 | * HTML转义 126 | * 127 | * @param string 128 | * @return string 129 | */ 130 | function html_encode(str) { 131 | return str.replace(/[<>&"]/g, function (c) { 132 | return { 133 | '<':'<', 134 | '>':'>', 135 | '&':'&', 136 | '"':'"' 137 | }[c]; 138 | }); 139 | } 140 | 141 | /** 142 | * 检测列表 143 | * 144 | * @return bool 145 | */ 146 | function testList() { 147 | if (q.list.length) 148 | return true; 149 | $title.text('没有歌曲'); 150 | $list.html('
    1. 没有歌曲
    2. '); 151 | $lyricOl.addClass('no').html('
    3. 暂无歌词,请欣赏
    4. '); 152 | return false; 153 | } 154 | 155 | var 156 | $player = $('#QPlayer'), 157 | $progress = $player.find('.progress'), 158 | $already = $progress.find('.already'), 159 | $title = $player.find('.title'), 160 | $audio = $player.find('audio'), 161 | $cover = $player.find('.cover img'), 162 | $timer = $player.find('.timer'), 163 | $play = $player.find('.play'), 164 | $more = $player.find('.more'), 165 | $list = $player.find('.list'), 166 | $listBtn = $player.find('.list-btn'), 167 | $lyric = $player.find('.lyric'), 168 | $lyricOl = $lyric.find('ol'), 169 | $lyricBtn = $player.find('.lyric-btn'), 170 | $listLi = $(), 171 | $lyricLi = $(), 172 | isLoad = false, 173 | isProgressClick = false, 174 | q = QPlayer, 175 | audio = q.audio = $audio[0], 176 | lyric = q.lyric = { 177 | arr: [], 178 | obj: {}, 179 | index: -1 180 | }; 181 | const 182 | 183 | /** 184 | * 网易云API 185 | * 186 | * @link https://github.com/moeshin/API-NeteaseMusic/ 187 | */ 188 | api1 = 'https://api.littlehands.site/NeteaseMusic/', 189 | 190 | /** 191 | * 重定向API 192 | * 193 | * @link https://github.com/moeshin/API-Redirect/ 194 | */ 195 | api2 = 'https://api.littlehands.site/Redirect/', 196 | 197 | lyricRegex1 = /(?:^|\n)((?:\[\d\d:\d\d\.\d{2,3}\])+)(.*)/g, 198 | lyricRegex2 = /\[(\d\d):(\d\d\.\d{2,3})\]/g; 199 | 200 | q.list = []; 201 | if (!q.type) { 202 | q.type = 'list'; 203 | } 204 | 205 | //获取播放歌单列表 206 | $.ajax({ 207 | url: api1, 208 | data: { 209 | type: q.type, 210 | id: q.id 211 | }, 212 | dataType: 'jsonp', 213 | success: function (json) { 214 | q.list = json; 215 | if (testList()) { 216 | //生成播放列表 217 | for (var i = 0; i < q.list.length; i++) { 218 | var data = q.list[i]; 219 | data.name = html_encode(data.name.replace(/\u00A0/g,'\u0020')); 220 | $list.append('
    5. '+data.name+''+data.artist.join('/')+'
    6. '); 221 | } 222 | 223 | $listLi = $list.find('li').click(function () { 224 | var obj = $(this); 225 | if (!obj.hasClass('error')) { 226 | // 清除当前历史节点之后的内容 227 | q.history = q.history.slice(0, ++q.histIndex); 228 | 229 | var index = obj.index(); 230 | q.play(index); 231 | q.history.push(index); 232 | } 233 | }); 234 | 235 | //触发监听事件 236 | q.isRotate = q.isRotate; 237 | q.isRandom = q.isRandom; 238 | 239 | q.listIndex = -1; 240 | q.histIndex = 0; 241 | q.load(random()); 242 | q.history = [q.listIndex]; 243 | $list[0].scrollTop = $list.find('.current')[0].offsetTop - $list[0].offsetTop + 1; 244 | if (q.isAuto) 245 | q.play(); 246 | } 247 | }, 248 | error: testList 249 | }); 250 | 251 | /** 252 | * 播放 253 | * 254 | * @param int 255 | */ 256 | q.play = function (n) { 257 | if (q.load(n)) 258 | return; 259 | $player.addClass('playing'); 260 | if (isLoad) { 261 | var id = q.current.id; 262 | isLoad = false; 263 | audio.load(); 264 | if (isExceedTitle()) 265 | $title.marquee({ 266 | duration: 15000, 267 | gap: 50, 268 | delayBeforeStart: 0, 269 | direction: 'left', 270 | duplicated: true 271 | }); 272 | $.ajax({ 273 | url: api2, 274 | data: { 275 | url: 'https://music.163.com/song/media/outer/url?id='+id, 276 | type: 1 277 | }, 278 | dataType: 'jsonp', 279 | success: function (json) { 280 | if (id !== q.current.id) 281 | return; 282 | var url = json[json.length - 1].url; 283 | if (/^https?:\/\/music.163.com\/404\b/.test(url)) { 284 | q.error(); 285 | return; 286 | } 287 | audio.src = url.replace(/^http:\/\//, 'https://'); 288 | q.playId = id; 289 | if ($player.hasClass('playing')) 290 | audio.play(); 291 | } 292 | }); 293 | } else { 294 | if (q.playId !== q.current.id || audio.networkState === 3) 295 | return; 296 | audio.play(); 297 | } 298 | }; 299 | 300 | /** 301 | * 加载 302 | * 303 | * @param n 304 | * @return boolean 是否跳过 305 | */ 306 | q.load = function (n) { 307 | if (typeof(n) === "number") { 308 | if (n < 0) { 309 | return true; 310 | } 311 | if ($listLi.eq(n).hasClass('error')) { 312 | if (q.history[q.histIndex] === n) { 313 | q.history.splice(q.histIndex--, 1); 314 | } 315 | q.next(); 316 | return true; 317 | } 318 | } else { 319 | // 首次初始化,不预加载音频,节省移动设备流量 320 | return false; 321 | } 322 | q.listIndex = n; 323 | $listLi.removeClass('current').eq(n).addClass('current'); 324 | var data = q.current = QPlayer.list[n]; 325 | $title.html(''+data.name+' - '+data.artist.join('/')+''); 326 | $cover.attr('src', data.pic.replace(/^http:\/\//i,'https://')); 327 | $already.width('0%'); 328 | $timer.text('00:00'); 329 | $lyricOl.addClass('no').html('
    7. 暂无歌词,请欣赏
    8. '); 330 | lyric.arr = []; 331 | lyric.obj = {}; 332 | lyric.index = -1; 333 | $lyricLi = $(); 334 | $.ajax({ 335 | url: api1, 336 | data: { 337 | type: 'lyric', 338 | id: data.id 339 | }, 340 | dataType: 'jsonp', 341 | success: function (json) { 342 | json.lyric.replace(lyricRegex1, function (match1, t, str) { 343 | var times = []; 344 | t.replace(lyricRegex2, function (match2, min, s) { 345 | times.push(min*60+s*1); 346 | }); 347 | for (var i = 0; i < times.length; i++) { 348 | var time = times[i]; 349 | lyric.arr.push(time); 350 | lyric.obj[time] = str?str:''; 351 | } 352 | }); 353 | json.tlyric.replace(lyricRegex1, function (match1, t, str) { 354 | var times = []; 355 | t.replace(lyricRegex2, function (match2, min, s) { 356 | times.push(min*60+s*1); 357 | }); 358 | for (var i = 0; i < times.length; i++) { 359 | var time = times[i]; 360 | if (lyric.obj[time] !== undefined) 361 | lyric.obj[time] += '
      '+str; 362 | else { 363 | lyric.arr.push(time); 364 | lyric.obj[time] = str?str:''; 365 | } 366 | } 367 | 368 | }); 369 | 370 | lyric.arr = lyric.arr.sort(function (a, b) { 371 | return a-b; 372 | }); 373 | if (lyric.arr.length > 0) 374 | $lyricOl.removeClass('no').html(''); 375 | for (var i = 0; i < lyric.arr.length; i++) { 376 | $lyricOl.append('
    9. '+lyric.obj[lyric.arr[i]]+'
    10. '); 377 | } 378 | $lyricLi = $lyricOl.find('li'); 379 | } 380 | }); 381 | isLoad = true; 382 | }; 383 | 384 | /** 385 | * 暂停 386 | * 387 | */ 388 | q.pause = function () { 389 | if (audio.networkState === 3) 390 | return; 391 | $player.removeClass('playing'); 392 | audio.pause(); 393 | }; 394 | 395 | /** 396 | * 下一首 397 | * 398 | */ 399 | q.next = function () { 400 | if (++q.histIndex < q.history.length) { 401 | q.play(q.history[q.histIndex]); 402 | } else { 403 | var index = random(); 404 | q.history.push(index); 405 | q.play(index); 406 | } 407 | }; 408 | 409 | /** 410 | * 上一首 411 | * 412 | */ 413 | q.last = function () { 414 | if (q.histIndex === 0) { 415 | if (q.isRandom) 416 | q.play(random()); 417 | else if (q.listIndex) 418 | q.play(q.listIndex-1); 419 | else 420 | q.play(q.list.length-1); 421 | q.history.splice(0,0,q.listIndex); 422 | q.histIndex = 0; 423 | } else 424 | q.play(q.history[--q.histIndex]); 425 | }; 426 | 427 | /** 428 | * 播放错误 429 | * 430 | */ 431 | q.error = function () { 432 | $listLi.eq(q.listIndex).addClass('error'); 433 | q.history.splice(q.histIndex--, 1); 434 | q.next(); 435 | }; 436 | 437 | /** 438 | * 设置rotate 439 | * 440 | * @param bool 441 | */ 442 | q.onSetRotate = function (bool) { 443 | if (bool) { 444 | $cover.attr('title', '点击不旋转封面'); 445 | $cover.addClass('rotate'); 446 | } else { 447 | $cover.attr('title', '点击旋转封面'); 448 | $cover.removeClass('rotate'); 449 | } 450 | }; 451 | 452 | /** 453 | * .pop-btn点击 454 | */ 455 | $player.find('.pop-btn').click(function () { 456 | $player.toggleClass('pop'); 457 | }); 458 | 459 | /** 460 | * 进度条按下 461 | */ 462 | $progress.mousedown(function (e){ 463 | if (!isProgressClick) { 464 | isProgressClick = true; 465 | $player.addClass('unselectable'); 466 | mouseProgress(e.pageX); 467 | } 468 | }).on('touchstart', function (e) { 469 | isProgressClick = true; 470 | $player.addClass('unselectable'); 471 | mouseProgress(e.originalEvent.changedTouches[0].pageX); 472 | }); 473 | 474 | /** 475 | * 文档操作 476 | */ 477 | $("body") 478 | .on('mouseup touchend', function () { 479 | if (isProgressClick) { 480 | isProgressClick = false; 481 | $player.removeClass('unselectable'); 482 | if (isNaN(audio.duration)) 483 | $already.width('0'); 484 | else { 485 | var time = audio.duration*$already.width()/$progress.width(); 486 | audio.currentTime = time; 487 | for (var i = 0; i < lyric.arr.length; i++) 488 | if (lyric.arr[i] >= time) { 489 | lyricSelect(lyric.index = i-1); 490 | break; 491 | } 492 | } 493 | 494 | } 495 | }).mousemove(function (e) { 496 | mouseProgress(e.pageX); 497 | }).on('touchmove',function (e) { 498 | if (isProgressClick) 499 | e.preventDefault(); 500 | mouseProgress(e.originalEvent.changedTouches[0].pageX); 501 | }); 502 | 503 | /** 504 | * .play点击 505 | */ 506 | $play.click(function () { 507 | if (q.list.length) 508 | if ($player.hasClass('playing')) 509 | q.pause(); 510 | else 511 | q.play(); 512 | }); 513 | 514 | /** 515 | * .next点击 516 | */ 517 | $player.find('.next').click(q.next); 518 | 519 | /** 520 | * .last点击 521 | */ 522 | $player.find('.last').click(q.last); 523 | 524 | 525 | $audio 526 | 527 | /** 528 | * 播放结束 529 | */ 530 | .on('ended', q.next) 531 | 532 | /** 533 | * 播放中 534 | */ 535 | .on('playing', function () { 536 | $player.addClass('playing'); 537 | $title.marquee('resume'); 538 | }) 539 | 540 | /** 541 | * 播放暂停 542 | */ 543 | .on('pause', function () { 544 | $player.removeClass('playing'); 545 | $title.marquee('pause'); 546 | }) 547 | .on('timeupdate', function () { 548 | $timer.text(sToMin(audio.currentTime)); 549 | if (!isProgressClick) 550 | $already.width(100*audio.currentTime/audio.duration+"%"); 551 | 552 | //播放歌词 553 | if (lyric.index+1 !== lyric.arr.length) 554 | if (lyric.arr[lyric.index+1] <= audio.currentTime) 555 | lyricSelect(++lyric.index); 556 | }) 557 | .on('error', q.error); 558 | 559 | $listBtn.click(function () { 560 | $more.toggleClass('list-show'); 561 | }); 562 | 563 | $lyricBtn.click(function () { 564 | $more.toggleClass('lyric-show'); 565 | }); 566 | 567 | $cover.click(function () { 568 | q.isRotate = !q.isRotate; 569 | }); 570 | 571 | }); 572 | --------------------------------------------------------------------------------