核心提示:很久没发文,一直想写点东西,整理整理这阵子的心得,很多笔记都在整理中。最近给公司编写的一个JS UI,用于歌词同步,整理一下放出来,核心脚本只负责处理lrc格式的歌词和呈现,并提供同步功能。外部呈现等...
很久没发文,一直想写点东西,整理整理这阵子的心得,很多笔记都在整理中。
最近给公司编写的一个JS UI,用于歌词同步,整理一下放出来,
核心脚本只负责处理lrc格式的歌词和呈现,并提供同步功能。

外部呈现等均可以良好定制。
基本调用如下:
var lrc=new LRC({lyricTable:obj,lyricWrapper:obj,curRowClassName:'xx',lyric:'xxx',separator:'
'});
if(lrc.IsLyricValid()) lrc.DoSync(60);
DoSync(t)用于同步,参数t为当前播放进度,从播放器获得。
IsLyricValid()返回歌词是否合法的LRC格式。
贴出代码,附件下载中包含2个定制示例。代码在FF下跑不了,因为音乐播放插件跑不了~

 Lrc UI
Lrc UI1

 /**//*
/**//*2
 *   @author:    huangxu
*   @author:    huangxu3
 *   @date:      2008-11
*   @date:      2008-114
 *   @site:  http://wsky.cnblogs.com
*   @site:  http://wsky.cnblogs.com5
 *   @descript:  sync display the lyric
*   @descript:  sync display the lyric 6
 *   @usage:
*   @usage:7
 *               //import lrc.css
*               //import lrc.css8
 *               var lrc=new LRC({lyricTable:obj,lyricWrapper:obj,curRowClassName:'xx',lyric:'xxx',separator:'
*               var lrc=new LRC({lyricTable:obj,lyricWrapper:obj,curRowClassName:'xx',lyric:'xxx',separator:''});
9
 *               if(lrc.IsLyricValid()) lrc.DoSync(60);
*               if(lrc.IsLyricValid()) lrc.DoSync(60);10
 *
*11
 *   @note:  内部变量前缀lrc_,普通变量i,ii,index,arg..
*   @note:  内部变量前缀lrc_,普通变量i,ii,index,arg..12
 */
*/13

14

 LRC=function()
LRC=function() {this.initialize.apply(this,arguments);}
{this.initialize.apply(this,arguments);}15

 LRC.prototype=
LRC.prototype= {
{16
 arrLyricTime:[],
    arrLyricTime:[],17
 arrLyric:[],//全局可用,必须执行初始化
    arrLyric:[],//全局可用,必须执行初始化18

 initialize:function(arg)
    initialize:function(arg) {
{19
 //私有
        //私有20
 this.lyricTable=arg.lyricTable;//目标歌词table
        this.lyricTable=arg.lyricTable;//目标歌词table21
 this.lyricWrapper=arg.lyricWrapper;//目标歌词容器div
        this.lyricWrapper=arg.lyricWrapper;//目标歌词容器div22
 this.curRowClassName=arg.curRowClassName;//选择行css样式名
        this.curRowClassName=arg.curRowClassName;//选择行css样式名23
 this.separator=arg.separator;//歌词行分隔符 如:
        this.separator=arg.separator;//歌词行分隔符 如:24
 //执行初始化
        //执行初始化25
 this.arrLyricTime=[];
        this.arrLyricTime=[];26
 this.arrLyric=[];
        this.arrLyric=[];27
 this.initArray(arg.lyric);
        this.initArray(arg.lyric);28
 this.arrLyricTime=this.sort(this.arrLyricTime);
        this.arrLyricTime=this.sort(this.arrLyricTime);29
 this.setLyricTable(this.arrLyric);
        this.setLyricTable(this.arrLyric);30
 },
    },31

 initArray:function(lyric)
    initArray:function(lyric) {
{32
 var lrc_re=new RegExp('\[[0-9:.]*\]','g');//g全局标志,获取所有匹配结果必须
        var lrc_re=new RegExp('\[[0-9:.]*\]','g');//g全局标志,获取所有匹配结果必须33
 var lrc_arr=lyric.split(this.separator);
        var lrc_arr=lyric.split(this.separator);34
 var lrc_temp=0;
        var lrc_temp=0;35
 var lrc_filter=0;//无效行过滤标记
        var lrc_filter=0;//无效行过滤标记36

 for(var i=0;i<lrc_arr.length;i++)
        for(var i=0;i<lrc_arr.length;i++) {
{37
 var lrc_txt=lrc_arr[i].replace(/\[[\w\W]*\]/g,'').Trim();//add to lyric text array
            var lrc_txt=lrc_arr[i].replace(/\[[\w\W]*\]/g,'').Trim();//add to lyric text array38

 if(lrc_txt=='')
            if(lrc_txt=='') {
{39
 lrc_filter++;
                lrc_filter++;40
 continue;
                continue;41
 }
            }       42
 this.arrLyric[i-lrc_filter]=lrc_txt;
            this.arrLyric[i-lrc_filter]=lrc_txt;43

 while((lrc_result = lrc_re.exec(lrc_arr[i])) != null)
            while((lrc_result = lrc_re.exec(lrc_arr[i])) != null) {
{44
 var lrc_second=this.parseSecond(lrc_result.toString().replace(/\[|\]/g,''));
                var lrc_second=this.parseSecond(lrc_result.toString().replace(/\[|\]/g,''));45
 if(!isNaN(lrc_second))
                if(!isNaN(lrc_second))46
 this.arrLyricTime[lrc_temp++]=(i-lrc_filter)+'|'+lrc_second;//arrLyricTime格式为"行号|秒",如:1|50,2|60
                    this.arrLyricTime[lrc_temp++]=(i-lrc_filter)+'|'+lrc_second;//arrLyricTime格式为"行号|秒",如:1|50,2|6047
 }
            }48
 }
        }49
 },
    },50
 /////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////51
 //  公开函数
    //  公开函数 52
 //  IsLyricValid()判断是否合法lrc歌词
    //  IsLyricValid()判断是否合法lrc歌词    53
 //  DoSync()定位歌词
    //  DoSync()定位歌词54
 /////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////55

 IsLyricValid:function(arrLyricTime)
    IsLyricValid:function(arrLyricTime) {
{56
 return this.arrLyricTime.length>0;
        return this.arrLyricTime.length>0;57
 },
    },58

 DoSync:function(curPosition)
    DoSync:function(curPosition) {
{59
 var lrc_times=this.arrLyricTime;
        var lrc_times=this.arrLyricTime;60

 for(var i=0;i<lrc_times.length;i++)
        for(var i=0;i<lrc_times.length;i++) {
{61
 var lrc_arrPre=lrc_times[i].split('|');
            var lrc_arrPre=lrc_times[i].split('|');62
 
            63
 if(i==0&&curPosition<lrc_arrPre[1]) break;//防止抖动
            if(i==0&&curPosition<lrc_arrPre[1]) break;//防止抖动64
 
            65

 if(lrc_times[i+1]==undefined)
            if(lrc_times[i+1]==undefined) {
{66
 this.setRow(lrc_arrPre[0]);
                this.setRow(lrc_arrPre[0]);67
 break;
                break;68
 }
            }69
 
            70
 var lrc_arrNext=lrc_times[i+1].split('|');
            var lrc_arrNext=lrc_times[i+1].split('|');71

 if(curPosition>=lrc_arrPre[1]&&curPosition<lrc_arrNext[1])
            if(curPosition>=lrc_arrPre[1]&&curPosition<lrc_arrNext[1]) {
{72
 this.setRow(lrc_arrPre[0]);
                this.setRow(lrc_arrPre[0]);73
 break;
                break;74
 }
            }75
 }
        } 76
 },
    },77
 /////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////78
 //以下为内部辅助函数
    //以下为内部辅助函数79
 /////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////80

 parseSecond:function(time)
    parseSecond:function(time) {
{81

 try
        try {
{82
 var lrc_arr=time.split(':');//time格式为时间格式 00:00
            var lrc_arr=time.split(':');//time格式为时间格式 00:0083
 return parseInt(lrc_arr[0])*60+parseFloat(lrc_arr[1]);
            return parseInt(lrc_arr[0])*60+parseFloat(lrc_arr[1]);84

 }catch(ex)
        }catch(ex) {
{85
 return 0;
            return 0;86
 }
        }87
 },
    },88

 setLyricTable:function(arrLyric)
    setLyricTable:function(arrLyric) {
{89
 this.lyricWrapper.scrollTop=0;//滚动条置顶
        this.lyricWrapper.scrollTop=0;//滚动条置顶90
 
        91

 if(this.lyricTable.rows.length>0)
        if(this.lyricTable.rows.length>0) {
{ 92
 this.clearTable(this.lyricTable);
            this.clearTable(this.lyricTable);93
 }
        }94

 for(var i=0;i<arrLyric.length;i++)
        for(var i=0;i<arrLyric.length;i++) {
{95
 var lrc_tr=this.lyricTable.insertRow();
            var lrc_tr=this.lyricTable.insertRow();96
 var lrc_cell=lrc_tr.insertCell(0);
            var lrc_cell=lrc_tr.insertCell(0);97
 lrc_cell.innerHTML=arrLyric[i];
            lrc_cell.innerHTML=arrLyric[i];98
 }
        }99
 },
    },100

 clearTable:function(lyricTable)
    clearTable:function(lyricTable) {
{101
 var lrc_rowNum=lyricTable.rows.length;
        var lrc_rowNum=lyricTable.rows.length;102

 for (var i=0;i<lrc_rowNum;i++)
        for (var i=0;i<lrc_rowNum;i++) {
{103
 lyricTable.deleteRow(i);
            lyricTable.deleteRow(i);104
 lrc_rowNum=lrc_rowNum-1;
            lrc_rowNum=lrc_rowNum-1;105
 i=i-1;
            i=i-1;106
 }
        } 107
 },
    },108

 setRow:function(index)
    setRow:function(index) {
{109
 this.setRowClass(index);
        this.setRowClass(index);110
 this.setScroll(index);
        this.setScroll(index);111
 },
    },112

 setRowClass:function(index)
    setRowClass:function(index) {
{113
 var lrc_rows=this.lyricTable.rows;
        var lrc_rows=this.lyricTable.rows;114

 for(var i=0;i<lrc_rows.length;i++)
        for(var i=0;i<lrc_rows.length;i++) {
{115
 lrc_rows[i].className='';//TODO:直接添加样式至元素,防止外部css干扰
             lrc_rows[i].className='';//TODO:直接添加样式至元素,防止外部css干扰116
 }
        }117
 lrc_rows[index].className=this.curRowClassName;
        lrc_rows[index].className=this.curRowClassName;118
 },
    },119

 setScroll:function(index)
    setScroll:function(index) {
{120
 this.lyricWrapper.scrollTop=this.lyricTable.rows[index].offsetTop-this.lyricWrapper.offsetHeight/3;
        this.lyricWrapper.scrollTop=this.lyricTable.rows[index].offsetTop-this.lyricWrapper.offsetHeight/3;121
 },
    },122

 sort:function(arrLyricTime)
    sort:function(arrLyricTime) {
{123

 for(var i=0;i<arrLyricTime.length-1;i++)
        for(var i=0;i<arrLyricTime.length-1;i++) {
{124

 for(var ii=i+1;ii<arrLyricTime.length;ii++)
            for(var ii=i+1;ii<arrLyricTime.length;ii++) {
{125
 var lrc_cur=parseFloat(arrLyricTime[i].split('|')[1]);
                var lrc_cur=parseFloat(arrLyricTime[i].split('|')[1]);126
 var lrc_next=parseFloat(arrLyricTime[ii].split('|')[1]);
                var lrc_next=parseFloat(arrLyricTime[ii].split('|')[1]);127

 if(lrc_cur>lrc_next)
                if(lrc_cur>lrc_next) {
{128
 var lrc_temp=arrLyricTime[i];
                    var lrc_temp=arrLyricTime[i];129
 arrLyricTime[i]=arrLyricTime[ii];
                    arrLyricTime[i]=arrLyricTime[ii];130
 arrLyricTime[ii]=lrc_temp;
                    arrLyricTime[ii]=lrc_temp;131
 }
                }132
 }
            }133
 }
        }    134
 return arrLyricTime;
        return arrLyricTime;135
 }
    }136
 }
}137

138

139
 /////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////140
 //外部函数
//外部函数141
 /////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////142
 String.prototype.Trim = function()
String.prototype.Trim = function()143


 {
{    144
 return this.replace(/^\s*|\s*$/g,"");
    return this.replace(/^\s*|\s*$/g,"");145
 }
}146




 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                 
            
                