PageSourceSearch

https://noteyd.chaoxing.com/res/plugin/smusic/js/smusic.js

js chaoxing.com collected 2026-09-24 15:31:41 UTC 32,701 bytes, 834 lines download raw bytes

1/**
2 * sMusic
3 * Author:Smohan
4 * Version: 2.0.0
5 * url: http://www.smohan.net/lab/smusic.html
6 * 使用请保留以上信息
7 */
8Smusic = {
9		global_audio : "",
10		currentMusicCid : ""
11}
12!(function(win, jQuery){
13    /**
14     * 添加样式
15     * @param element
16     * @param className
17     */
18    function addClass(element,className){
19        if(hasClass(element,className) == false){
20            element.className += ' '+className;
21        }
22    }
23    /**
24     * 是否包含样式
25     * @param element
26     * @param className
27     * @returns {boolean}
28     */
29    function hasClass(element,className){
30        return !!element.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
31    }
32    /**
33     * 移除样式
34     * @param element
35     * @param className
36     */
37    function removeClass(element,className){
38        var currentClass = element.className;
39        if(hasClass(element,className)){
40            currentClass = currentClass.replace(new RegExp('(\\s|^)'+className+'(\\s|$)'),' ');
41            currentClass = currentClass.replace(/(^\s*)|(\s*$)/g,'');
42            element.className = currentClass;
43        }
44    }
45    /**
46     * 自动添加或删除样式(自动切换)
47     * @param element
48     * @param className
49     */
50    function toggleClass(element,className){
51        if(hasClass(element,className)){
52            removeClass(element,className);
53        }else{
54            addClass(element,className);
55        }
56    }
57    /**
58     * 返回元素节点
59     * @param element
60     * @returns {HTMLElement}
61     */
62    function $(element){
63        return document.querySelector(element);
64    }
65    /**
66     * 对象扩展
67     * @param target
68     * @param source
69     * @returns {object}
70     */
71    function extend(target,source){
72        for(var p in source){
73            if(source.hasOwnProperty(p)){
74                target[p] = source[p];
75            }
76        }
77        return target;
78    }
79    /**
80     * 格式化时间
81     * @param time
82     * @returns {string}
83     */
84    function calcTime(time){
85        if (musicPlayer.musicList.length == 0) {
86        	return "00:00";
87        }
88    	
89    	var hour,minute,second,timer = '';
90        hour = String(parseInt(time/3600,10));
91        minute = String(parseInt((time % 3600) / 60 ,10));
92        second = String(parseInt(time % 60, 10));
93        if(hour != '0'){
94            if(hour.length == 1) hour = '0' + hour;
95            timer += (hour + ':');
96        }
97        if(minute.length == 1) minute = '0' + minute;
98        timer += (minute + ':');
99        if(second.length == 1) second = '0' + second;
100        timer += second;
101        
102        return timer;
103    }
104
105    /**
106     * 简单Ajax请求
107     * @param url
108     * @param callback
109     * @returns {boolean}
110     */
111    function ajax(url,callback,method){
112    	if (!method) {
113    		method = "GET";
114    	}
115    	
116        if(!url) return false;
117        var xhr = new XMLHttpRequest();
118        xhr.onreadystatechange = function () {
119            if (xhr.readyState == 4) {
120                var status = xhr.status;
121                //console.log(status);
122                if((status >= 200 && status < 300) || status == 304){
123                    (callback && typeof callback == "function") && callback(xhr.responseText);
124                    return true;
125                }else{
126                    return new Error("ajax请求失败");
127                }
128            }
129        };
130        xhr.open(method, url,true);
131        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
132        xhr.send();
133        return true;
134    }
135   /* ajax("./README.md", function (res) {
136        console.log(res);
137    });*/
138    var bufferTimer = null;
139    /**
140     * 构造函数
141     * @param config
142     * @constructor
143     */
144    function SmohanMusic(config){
145        var defaults = this.config;
146        this.config = extend(defaults,config);
147        this.musicList = this.config.musicList || [];
148        this.musicLength = this.musicList.length;
149        if(!this.musicLength || !$('body')){
150            this.musicDom.listWrap.innerHTML = '<p>暂无播放记录...</p>';
151        }
152        this.audioDom = null; //audio对象
153        this.init();
154    }
155    SmohanMusic.prototype = {
156        config : {
157            musicList : [],    //播放列表
158            defaultVolume :.7,  //初始化音量 0 - 1.0 之间
159            defaultIndex  : 0,  //初始化播放索引
160            autoPlay  : false,  //是否自动播放
161            defaultMode : 1,     //播放模式
162            callback    : function(_thisPlayer,obj){},  //回调函数,返回当前播放媒体信息
163            loadMusic : function(_thisPlayer,_music){} //如果歌曲_music不在或者地址_music.src为空,加载歌曲,返回true|false是否加载成功
164        },
165        /**
166         * 删除一首歌曲
167         */
168        deleteMusic : function (resid, self) {
169        	var index;
170        	for (var i in this.musicList) {
171        		if (this.musicList[i]['resid'] == resid) {
172        			index = i;
173        			break;
174        		}
175        	}
176        	
177        	this.musicList.splice(index, 1)
178        	this.musicLength = this.musicList.length;
179        	if (this.musicList.length == 0) {
180        		this.pause();
181        		this.audioDom.currentTime = 0;
182        		jQuery(".u-music-title > strong").text("");
183        		jQuery(".u-music-title > strong").removeAttr("title");
184        		
185        	} else if (jQuery(self).parent('li').attr("class") == "f-toe current") {
186        		this.playByMode("next");
187        	}
188        	jQuery(self).parent('li').remove();
189        },
190        /**
191         * 添加一首歌到播放列表中
192         */
193        addMusic : function(oneMusic) {
194        	this.musicList.push({
195				'resid': oneMusic.resid,
196    			'title': oneMusic.title,
197    			'src': oneMusic.src,
198    		});
199        	this.musicLength = this.musicList.length;
200    		
201			var music = this.createMusicDom(oneMusic.resid, oneMusic.title);
202			var _tmpMusicPlayer = this;
203			music.bind('click', {'self': _tmpMusicPlayer, 'resid':oneMusic.resid}, function(e) {
204				var index = 0;
205				for (var i in _tmpMusicPlayer.musicList) {
206					if (_tmpMusicPlayer.musicList[i]['resid'] == oneMusic.resid) {
207						index = i;
208						break;
209					}
210				}
211				
212				_tmpMusicPlayer.resetPlayer(index);
213			});
214    		jQuery(".m-music-list-wrap > ul").append(music);
215    		music.click();
216        },
217        /**
218         * 创建音乐列表中的一个元素
219         */
220        createMusicDom : function(resid, title) {
221        	var del = jQuery("<span class=\"delete\"> </span>");
222        	del.bind('click', {'self': this, 'resid': resid}, function(e) {
223        		e = e||event; 
224    			e.stopPropagation();
225        		
226        		e.data.self.deleteMusic(resid, this);
227        	});
228        	
229        	return jQuery("<li class=\"f-toe\" musicresid=\""+resid+"\"><strong>"+ title + "</strong></li>").append(del);;
230        },
231        /**
232         * 创建播放列表
233         */
234        createListDom : function() {
235            var ul = jQuery("<ul></ul>");
236            
237            for(i = 0; i < this.musicLength; i++) {
238            	var li = this.createMusicDom(this.musicList[i]['resid'], this.musicList[i]['title']);
239                ul.append(li).append("<hr>");
240            }
241            
242            jQuery(this.musicDom.listWrap).append(ul);
243        },
244        /**
245         * 缓冲加载
246         */
247        setBuffer : function(audio,bufferDom){
248            var w =  $('.old-bar').offsetWidth.offsetWidth;
249            bufferTimer = setInterval(function(){
250                var buffer = audio.buffered.length;
251                if(buffer > 0 && audio.buffered != undefined){
252                    var bufferWidth =  (audio.buffered.end(buffer-1) / audio.duration) * w;
253                    bufferDom.style.width = bufferWidth + 'px';
254                    if(Math.abs(audio.duration - audio.buffered.end(buffer-1)) <1){
255                        bufferDom.style.width = w + 'px';
256                        clearInterval(bufferTimer);
257                    }
258                }
259            },100);
260        },
261        /**
262         * 重载播放器
263         * @param idx
264         */
265        resetPlayer : function(idx){
266            (idx >= (this.musicLength-1)) && (idx = (this.musicLength-1));
267            (idx <= 0) && (idx = 0);
268            this.currentMusic = idx;
269            var nowMusic = this.musicList[idx],  //获取当前的播放音乐信息
270                me = this;
271            if(!nowMusic||!nowMusic.src||nowMusic.src.replace(/ /g,'')==""){
272            	if(!this.config.loadMusic(me,nowMusic)){
273            		return ;
274            	};
275            }
276            //过渡函数,用于事件监听和移除,暂时性的解决通过addEventListener添加的事件传递匿名函数无法移除的问题
277            var tempBuffer = function(){
278                return me.setBuffer(this,me.musicDom.bufferProcess);
279            };
280            //在canplay事件监听前移除之前的监听
281            this.audioDom.removeEventListener('canplay',tempBuffer,false);
282            clearInterval(bufferTimer);
283            //样式重置(元素属性重新设置)
284            this.musicDom.bufferProcess.style.width = 0+'px';
285            this.musicDom.curProcess.style.width = 0 + 'px';
286            this.musicDom.currentBar.style.left=0+'px';
287            this.audioDom.src = nowMusic.src;
288            var len=this.audioDom.src.length;
289            var pointPosition=this.audioDom.src.lastIndexOf('.');
290            
291            // this.musicDom.cover.innerHTML = '<img src="'+nowMusic.cover+'" title="">';
292            this.musicDom.title.innerHTML = "<strong title='"+ nowMusic.title +"'>"+ nowMusic.title +"</strong>";
293
294
295            me.musicDom["lyricWrap"].innerHTML = '<li class="eof">正在加载歌词...</li>';
296            me.musicDom["lyricWrap"].style.marginTop = 0 + "px";
297            me.musicDom["lyricWrap"].scrollTop = 0;
298            this.getLyric(idx);
299            
300            //设置播放列表选中
301            var playlist = document.querySelectorAll('.m-music-list-wrap li'), i = 0;
302            for(i; i< this.musicLength;i++){
303                if(i == idx){
304                    addClass(playlist[i],'current');
305                }else{
306                    removeClass(playlist[i],'current');
307                }
308            }
309            //可以播放时,设置缓冲区,重新监听 canplay  PS:当音频能够播放时,才会触发该事件
310            this.audioDom.addEventListener('canplay',tempBuffer,false);
311            if(this.config.autoPlay){  //增加是否启动就播放的开关
312                this.play();
313            }else{
314                this.pause();
315            }
316            var _callback = nowMusic;
317            _callback.index = idx;
318            typeof this.config.callback == "function" && this.config.callback(me,_callback);  //将当前播放信息回调
319        },
320        /**
321         * 音量设置
322         * @param volume
323         */
324        setVolume : function(volume){
325            var v = this.musicDom.volume,
326                h = v.volumeProcess.offsetHeight || 50;  //隐藏元素的高度不好获取,这里设置visible来实现同样的效果
327            if(volume <= 0) volume = 0;
328            if(volume >= 1) volume = 1;
329            this.audioDom.volume = volume;
330            var currentHeight = h * volume;
331            // if(currentHeight>60){
332            //     currentHeight=60;
333
334            // }
335            v.volumeCurrent.style.height = currentHeight + 'px';
336            v.volumeCtrlBar.style.bottom = currentHeight + 'px';
337            v.volumeProcess.setAttribute('data-volume',volume);
338             
339            if(volume < 0.1){
340                //静音
341                addClass(v.volumeControl,'muted');
342                this.audioDom.muted = true;
343            }else{
344                removeClass(v.volumeControl,'muted');
345                this.audioDom.muted = false;
346            }
347        },
348        /**
349         * 初始化播放器
350         */
351        initPlay : function(){
352            var idx = this.config.defaultIndex;
353            if(this.playMode == 2){ //随机播放
354                idx = this.getRandomIndex();
355            }
356            this.setVolume(this.config.defaultVolume);
357            this.audioDom.load();
358            this.resetPlayer(idx);
359        },
360        /**
361         * 播放
362         */
363        play : function(ele){
364        	if (this.musicList.length <= 0) {
365        		return ;
366        	}
367        	var changeInd = undefined;
368        	if(ele){
369	        	if(typeof ele =="integer" && this.musicList[ele]){
370	        		changeInd = ele;
371	        	}else{
372	        		for(md in this.musicList){
373	        			if(this.musicList[md]["resid"]==ele){
374	        				changeInd = md;
375	        				break;
376	        			}
377	        		}
378	        	}
379        	}
380//        	console.log("play:"+changeInd);
381        	if(changeInd){
382        		this.resetPlayer(changeInd);
383        		return;
384        	}
385            var ctrl = this.musicDom.button.ctrl;
386            this.audioDom.play(); 
387            removeClass(ctrl,'paused');
388            addClass(ctrl,'play');
389            ctrl.setAttribute('title','暂停');
390            removeClass(this.musicDom.cover,'paused');
391            addClass(this.musicDom.cover,'play');
392            
393            // 播放当前音频时,通知其他在播放的音频附件停止动画效果
394            var iframes = '';
395            var ueditor_iframe = window.frames["ueditor_0"];
396        	if(ueditor_iframe) {
397        		// 编辑页
398        		var doc = ueditor_iframe.contentDocument || ueditor_iframe.document;
399				if(doc) {
400					iframes = doc.getElementsByTagName('iframe');
401				}
402        	} else {
403        		// 详情页
404        		iframes = document.getElementsByTagName('iframe');
405        	}
406            if(iframes && iframes.length > 0) {
407            	for(i=0; i<iframes.length; i++) {
408            		var src = iframes[i].getAttribute('src');
409            		if(src && src.indexOf("insertVoice") > -1) {
410            			Smusic.currentMusicCid = this.musicList[this.currentMusic].iframe_cid;
411            			iframes[i].contentWindow.postMessage({'cid': this.musicList[this.currentMusic].resid, 'onlyAnimation':true,'action':'play'}, "https://noteyd.chaoxing.com");
412            		}
413            	}
414            }
415        },
416        /**
417         * 暂停
418         */
419        pause : function(){
420            var ctrl = this.musicDom.button.ctrl;
421            this.audioDom.pause();
422            removeClass(ctrl,'play');
423            addClass(ctrl,'paused');
424            ctrl.setAttribute('title','播放');
425            removeClass(this.musicDom.cover,'play');
426            addClass(this.musicDom.cover,'paused');
427            
428            // 停止播放音频时,通知音频iframe停止动画
429            var iframes = '';
430        	var ueditor_iframe = window.frames["ueditor_0"];
431        	if(ueditor_iframe) {
432        		// 编辑页
433        		var doc = ueditor_iframe.contentDocument || ueditor_iframe.document;
434				if(doc) {
435					iframes = doc.getElementsByTagName('iframe');
436				}
437        	} else {
438        		// 详情页
439        		iframes = document.getElementsByTagName('iframe');
440        	}
441            if(iframes && iframes.length > 0) {
442            	for(i=0; i<iframes.length; i++) {
443            		var src = iframes[i].getAttribute('src');
444            		if(src && src.indexOf("insertVoice") > -1) { 		
445            			iframes[i].contentWindow.postMessage({'cid': this.musicList[this.currentMusic].resid, 'onlyAnimation':true,'action':'paused'}, "https://noteyd.chaoxing.com");
446            		}
447            	}
448            }
449        },
450        /**
451         * 获取不包含当前索引的随机索引
452         * @returns {number}
453         */
454        getRandomIndex : function(){
455            var idx = this.currentMusic,len  = this.musicLength, i = 0, temp = [];
456            //应该在不包括当前的列表中播放
457            for(i;i<len;i++){
458                if(i != idx){
459                    temp.push(i);
460                }
461            }
462            var random = parseInt(Math.random() * temp.length);
463            return temp[random];
464        },
465        /**
466         * 通过播放模式加载歌曲并播放
467         * @param type
468         */
469        playByMode : function(type){
470            var modes = this.playMode,
471                idx  = this.currentMusic,
472                len  = this.musicLength,
473                index = idx;
474            if(modes == 1){  //列表
475                if(type == 'prev'){
476                    index = ((idx <= len - 1) && (idx > 0)) ? (idx-1) : (len-1);
477                }else if(type == 'next' || type == 'ended'){  //增加一个ended区别单曲循环
478                    index = (idx >= len - 1) ? 0 : (idx+1);
479                }
480            }else if(modes == 2){ //随机
481                index = this.getRandomIndex();  //无论上下曲,随机获取一个不是当前播放的索引
482            }else if(modes == 3){ //单曲
483                if(type == 'prev'){
484                    index = ((idx <= len - 1) && (idx > 0)) ? (idx-1) : (len-1);
485                }else if(type == 'next'){
486                    index = (idx >= len - 1) ? 0 : (idx+1);
487                }else{
488                    index = idx;
489                }
490            }
491            this.resetPlayer(index);
492        },
493        /**
494         * 一些操作
495         */
496        action : function(){
497            var  me = this, v = this.musicDom.volume, btn = this.musicDom.button;
498            //监听timeupdate,设置进度,PS:播放过程中,当前播放位置改变时,会触发该事件
499            this.audioDom.addEventListener('timeupdate',function(){
500                var audio = this;
501                Smusic.global_audio = this;
502                if(!isNaN(audio.duration)){
503                    var surplusTime = calcTime(audio.currentTime),
504                        totalTime   = calcTime(audio.duration);
505                    var currentProcess = (audio.currentTime / audio.duration) * ($('.old-bar').offsetWidth);
506                    //当前播放时间/总时间 = 播放百分比
507                    //播放百分比 * 进度条长度 = 当前播放进度
508                    me.musicDom.time.innerHTML = ''+totalTime+'';
509                    me.musicDom.startTime.innerHTML=''+surplusTime+'&nbsp;&nbsp;';
510                    me.musicDom.curProcess.style.width = currentProcess + 'px';
511                     
512                    // var left=me.musicDom.currentBar.style.left
513                    // if(currentProcess>302){
514                    //     currentProcess=302;
515                    // }
516                    me.musicDom.currentBar.style.left= -1+ currentProcess+'px';
517                    //歌词滚动
518                    //设置歌词
519                    var curTime = parseInt(audio.currentTime*1e3);
520                    var lyrics  = me.musicDom["lyricWrap"].querySelectorAll(".u-lyric"),
521                        sizes   = lyrics.length,
522                        i       = 0;
523                    if(sizes > 1){
524                        for(;i < sizes ; i++){
525                            var lyl = lyrics[i];
526                            if(lyl){
527                                var _time = parseFloat(lyl.getAttribute("data-time"));
528                                if(curTime >= _time){
529                                    var top = (i-1) * 30; //30是每个LI的高度
530                                    me.musicDom["lyricWrap"].style.marginTop = -top + "px";
531                                    //移除之前的current,想念Jquery的siblings
532                                    for(var j = 0 ; j < sizes ;j++){
533                                        lyrics[j] && removeClass(lyrics[j],"current");
534                                    }
535                                    addClass(lyl,"current"); //给当前行加上current
536                                }
537                            }
538                        }
539                    }
540                }
541            },false);
542            //监听 播放结束,PS:当音频播放完毕或者播放结束时会触发ended事件
543            this.audioDom.addEventListener('ended',function(){
544                me.playByMode('ended');
545            },false);
546            //显示隐藏音量控制器,静音等操作
547
548
549            v.volumeControl.addEventListener('click',function(event){
550                event = event || window.event;
551                event.stopPropagation();             
552                   if(v.volumeEventer.style.visibility=='hidden'||!v.volumeEventer.style.visibility){
553                    v.volumeEventer.style.visibility='visible';
554                   }else{
555                    v.volumeEventer.style.visibility='hidden';
556                   }                                
557            },false);
558
559                 
560
561            //静音
562//             v.volumeControl.addEventListener('click',function(event) {
563//            	 event = event || window.event;
564//                 event.stopPropagation();                      
565//                 toggleClass(this,'muted');
566//                 hasClass(this,'muted') ? (me.audioDom.muted = true) : (me.audioDom.muted = false);
567//            },false);
568             
569            // ffffff
570            // v.volumeProcess.addEventListener('mouseout',function(event){
571            //     event = event || window.event;
572            //     event.stopPropagation();
573            //     // if(hasClass(v.volumeProcess,'show')){
574            //     //     toggleClass(this,'muted');
575            //     //     hasClass(this,'muted') ? (me.audioDom.muted = true) : (me.audioDom.muted = false);
576            //     // }else{
577            //         removeClass(v.volumeProcess,'show');  //显示
578            //     // }
579            // },false);
580            //  
581             
582            //区域外点击隐藏控制器
583            document.addEventListener('click',function(event){
584                event = event || window.event;
585                event.stopPropagation();
586                var target = event.target || event.srcElement;
587                if((target.parentNode !== v.volumeEventer) && target.parentNode !== $('.grid-music-container .u-volume')){
588                    //当触发事件的元素不在音量元素范围里时关闭
589                    v.volumeEventer.style.visibility='hidden';
590                }
591            },false);
592            
593            //音量控制
594            v.volumeEventer.addEventListener('click',function(event) {
595//            	var objTop = this.offsetHeight;//对象y位置
596//                var mouseY = event.clientY+document.body.scrollTop;//鼠标y位置
597//                
598//                //计算点击的相对位置
599//                console.log(objTop,mouseY);
600//                var objY =  155-mouseY;
601//                console.log(objY/78);
602
603                event = event || window.event;
604                event.stopPropagation();
605                var h = this.offsetHeight,
606                y = event.offsetY;  //获取距离父级相对位置
607//                y1=event.clientY - 40;
608                
609                var volume = (h - y) / h;
610                console.info(volume);
611                me.setVolume(volume);
612            },false);
613            
614            //点击列表切歌
615            var playlist = document.querySelectorAll('.m-music-list-wrap li'), i = 0;
616            for(i; i< me.musicLength;i++){
617                playlist[i].addEventListener('click',function(){
618                	var tmpInd = i;
619                	for(mind in me.musicList){
620                		if(me.musicList[mind]["resid"]==this.getAttribute("musicresid")){
621                			tmpInd = mind;
622                		}
623                	}
624                    me.resetPlayer(tmpInd);
625                },false);
626            }
627            //暂停/播放
628            btn.ctrl.addEventListener('click',function(){
629                if(hasClass(this,'play')){
630                    me.pause();
631                }else{
632                    me.play();
633                }
634            },false);
635            //上一曲
636            btn.prev.addEventListener('click',function(){
637                me.playByMode('prev');
638            },false);
639            //下一曲
640            btn.next.addEventListener('click',function(){
641                me.playByMode('next');
642            },false);
643            //模式选择
644            //列表循环
645            btn.order.addEventListener('click',function(){
646                 
647                if(hasClass(this,'mode-list')){
648                    addClass(this,'mode-random');
649                    removeClass(this,'mode-list');
650                    
651                    this.title='随机播放';  
652                    
653                    me.playMode = 2;
654                }else if(hasClass(this,'mode-random')){
655                    addClass(this,'mode-single');
656                    removeClass(this,'mode-random');
657                    this.title='单曲循环';
658                    me.playMode = 3;
659                }else if(hasClass(this,'mode-single')) {
660                    addClass(this,'mode-list');
661                    removeClass(this,'mode-single');
662                    this.title='列表循环';
663                    me.playMode = 1;
664                }
665                
666            });
667
668
669            //随机播放
670            // btn.randomPlay.addEventListener('click',function(){
671            //     removeClass(this,'current');
672            //     removeClass(this,'mode-random');
673            //     addClass(btn.singleCircular,'current');
674            //     addClass(btn.singleCircular,'mode-single');
675            //     me.playMode = 3;
676            // });
677            // //单曲循环
678            // btn.singleCircular.addEventListener('click',function(){
679            //     removeClass(this,'current');
680            //     removeClass(this,'mode-single');
681            //     addClass(btn.listCircular,'current');
682            //     addClass(btn.listCircular,'mode-list');
683            //     me.playMode = 1;
684            // });
685            //拖动进度条,快进
686
687            var $progress = this.musicDom["curProcess"].parentNode;
688
689            $progress.addEventListener("click",function(e){
690                e = e || window.event;
691                var left = this.getBoundingClientRect().left,width = this.offsetWidth;
692                // console.log(left);
693                var progressX = Math.min(width,Math.abs(e.clientX - left)); //防止超出范围
694                if(me.audioDom.currentTime && me.audioDom.duration){
695                    me.audioDom.currentTime = parseInt((progressX / width) * (me.audioDom.duration)); //重新设置播放进度
696                    me.play();
697                }    
698            });
699        },
700        /**
701         * 加载歌词
702         * 目前只支持UTF8编码
703         * 不支持跨域,如果要跨域则自行更改ajax为jsonp
704         * @param index
705         */
706        getLyric : function (index) {
707            if(this.lyricCache[index]){
708                this.renderLyric(this.lyricCache[index]);
709            }else{
710                var url = this.musicList[index]["lyric"], me = this;
711                if(url){
712                    ajax(url, function (data) {
713                        me.lyricCache[index] = data ? data : null;
714                        me.renderLyric(data);
715                    });
716                }else{
717                    this.lyricCache[index] = null;
718                    me.renderLyric(null);
719                }
720            }
721        },
722        /**
723         * 解析歌词
724         * 歌词按时间分组并存储到数组
725         * [{content: "车站 (Live) - 李健↵",time: 800}...]
726         * @param lyric
727         * @returns {*}
728         */
729        parseLyric : function (lyric) {
730            if(!lyric) return lyric;
731            var result = [];
732            var cArr = lyric.split("[");
733            cArr.shift();
734            for (var i = 0; i < cArr.length; i++) {
735                var o = cArr[i].split("]");
736                if (o.length >= 2 && o[1] != "") {
737                    var tArr = o[0].split(":"), t = 0;
738                    if (tArr.length >= 2) {
739                        var mtArr = tArr[0].split(""), mt = 0;
740                        for (var k = 0; k < mtArr.length; k++) {
741                            if (Number(mtArr[k]) > 0) {
742                                mt += mtArr[k] * Math.pow(10, mtArr.length - k - 1);
743                            }
744                        }
745                        t += mt * 60;
746                        var stArr = tArr[1].split("."), intStArr = stArr[0].split(""), st = 0;
747                        for (var j = 0; j < intStArr.length; j++) {
748                            if (Number(intStArr[j]) > 0) {
749                                st += intStArr[j] * Math.pow(10, intStArr.length - j - 1);
750                            }
751                        }
752                        t += Number(st + "." + stArr[1]);
753                    }
754                    if(t && typeof t == "number"){
755                        result.push({time : parseInt(t * 1e3), content : o[1]});
756                    }
757                }
758            }
759            return result;
760        },
761        /**
762         * 渲染歌词
763         * @param lyric
764         */
765        renderLyric : function (lyric) {
766            lyric = this.parseLyric(lyric);
767            var me = this, dom = me.musicDom["lyricWrap"], tpl = "",len, i = 0;
768            len = lyric ? lyric.length : 0;
769            if(lyric && len){
770                for( i ; i < len ; i ++){
771                    var data = lyric[i];
772                    var time = data["time"], text = data["content"].trim();
773                    text = text ? text : '--- smusic ---';
774                    tpl += '<li class="u-lyric f-toe" data-time="'+time+'">'+text+'</li>';
775                }
776                tpl && (tpl += '<li class="u-lyric">www.smohan.net</li>');
777            }else{
778                tpl = '<li class="eof">暂无歌词...</li>';
779            }
780            dom.style.marginTop = 0 + "px";
781            dom.screenTop = 0;
782            dom.innerHTML = tpl;
783        },
784        /**
785         * 初始化播放器
786         */
787        init : function(){
788            //缓存DOM结构
789            this.musicDom = {
790                music : $('.grid-music-container'),
791                cover : $('.grid-music-container'),
792                title : $('.grid-music-container .u-music-title'),
793                curProcess : $('.grid-music-container .current-process'),
794                bufferProcess : $('.grid-music-container .buffer-process'),
795                currentBar:$('.grid-music-container .current-bar'),
796                time : $('.grid-music-container .u-time'),
797                startTime:$('.startTime'),
798                listWrap : $('.grid-music-container .m-music-list-wrap'),
799                lyricWrap : $('.grid-music-container .js-music-lyric-content'), //歌词区域
800                volume   : {
801                    volumeProcess : $('.grid-music-container .volume-process'),
802                    volumeCurrent : $('.grid-music-container .volume-current'),
803                    volumeCtrlBar : $('.grid-music-container .volume-bar'),
804                    volumeEventer : $('.grid-music-container .volume-event'),  //主要作用于绑定事件,扩大了音量的触发范围
805                    volumeControl : $('.grid-music-container .volume-control'),
806                    parentVolume  :$('.grid-music-container .u-volume')  ,
807                    current:$('.grid-music-container .current'),
808                    
809                   
810                },
811                button  : {
812                    ctrl : $('.grid-music-container .ctrl-play'),
813                    prev : $('.grid-music-container .prev'),
814                    next : $('.grid-music-container .next'),
815                     order:$('.grid-music-container .mode'),
816                    listCircular : $('.grid-music-container .mode-list'), //列表循环
817                    randomPlay   : $('.grid-music-container .mode-random'), //随机循环
818                    singleCircular : $('.grid-music-container .mode-single') //单曲循环
819                }
820            };
821            this.currentMusic = this.config.defaultIndex || 0;
822            this.playMode = this.config.defaultMode || 1; //播放模式,默认列表循环
823            this.lyricCache = {}; //缓存已加载的歌词文件
824            this.audioDom = document.createElement('audio');
825            this.createListDom();
826            this.initPlay();
827            this.action();
828        }
829    };
830    //重新封装,实例化后返回一个全局对象
831    window.SMusic = function(options){
832        return new SmohanMusic(options);
833    };
834})(window, jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.