• JS时间轴效果(类似于qq空间时间轴效果)


     

    2013-11-04 23:51 by 空智, 4041 阅读, 15 评论, 收藏, 编辑

           在上一家公司写了一个时间轴效果,今天整理了下,感觉有必要写一篇博客出来 给大家分享分享 当然代码还有很多不足的地方,希望大家多指点指点下,此效果类似于QQ空间或者人人网空间时间轴效果,当时也是为了需求 研究了下qq空间逻辑(当然JS代码压缩了肯定看不到的),只是当时研究了下他们HTML结构和css结构,所以仿照他们那种逻辑自己也写了一个出来。先来看看是个什么样的吧!如下图所示:

    需求分析:左侧是一个时间列表 右侧是一个时间控制抽,当时的需求是这样的:默认页面一打开 只加载当前年份所有列表加载出来 当前年份的控制轴展开出来,默认的焦点在最近的月份,如上图在当前的10月份或者下图的12月份,当滚动条滚动的时候再继续判断 如果左侧滚动到几月份的时候 那么右侧控制抽当前的焦点也在几月份,当滚动到上一个年份的时候 那么当前的年份控制轴收缩起来 上一个年份控制轴展开出来,如下图所示:

     

    当我们点击某一年份的时候 滚动到当前的年份,当我点击某一年中某一月份的时候 滚动到当前年份中对应的月份上来。

    当然下面的代码我是用到的是淘宝的KISSY框架  当然如果改成Jquery框架也是一样的,没有很大的差别 只是用了一下"延迟加载"和一些选择器而已,首先我们如果要做成这样的话 要知道有2个请求 一个是左侧列表请求返回的数据 一个是右侧的年份和月份返回的数据 下面我们可以先来看看 开发给我当时返回的数据格式是个什么样的,

    左侧列表的JSON数据如下图:

    默认情况下是最近年份 当我滚动到2012年时候 再继续发个2012年的请求 把2012年的相对应的数据渲染出来,同理2011年也一样.

    再来看看年份和月份的JSON数据吧 如下图:

    下面我一步步来分析下 我当时的做法:

    1. 首先我需要HTML结构 如下图所示:

    复制代码
    <div class="tao-allMonth-w990"> 
            <div class="tao-video-left J_Video_Left" id="J_Video_Left"></div> 
            <div class="tao-year-right"> 
                <div class="mod-timelinenav"> 
                    <ul id="timelinenavpanel" class="timelinenav-panel isScroll"></ul> 
                </div> 
            </div> 
        </div>
    复制代码

    其中 id="J_Video_Left" 和 id="timelinenavpanel" 在初始化的时候 是可以配置的 也就是说 他们叫什么名字并不重要,依赖于这个HTML结构。

    2. 依赖于css代码 如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    <style>
         .tao-allMonth-w990 {width: 990px;margin: 100px auto 0;overflow: hidden;    }
        .tao-video-left {float:left;width: 620px;overflow: hidden;}
        .tao-video-block {width: 620px;overflow: hidden;}
        .tao-header-title {width: 100%;height: 26px;overflow: hidden;}
        .tao-header-title {color: #FF6600;font-family: "Microsoft yahei";font-size: 18px;font-weight: 700;padding-left: 42px;}
        .tao-dottle-top {width: 10px;height: 40px;margin-left: 68px;background: none repeat scroll 0 0 #FFCC99;overflow: hidden;    }
        .tao-video-content {position: relative;width: 620px;overflow: hidden;}
        .tao-video-content .addBlock {
            background: none repeat scroll 0 0 #FFCC99;
            height: 16px;
            left: 68px;
            position: absolute;
            width: 10px;
        }
        .left-date {
            color: #FF6600;
            float: left;
            font-family: "Microsoft yahei";
            font-size: 14px;
            height: 20px;
            line-height: 20px;
            margin-top: 18px;
            overflow: hidden;
            width: 60px;
        }
        .left-date span {
            float: left;
        }
        .tao-video-content .tao-line {
            background: url("http://img02.taobaocdn.com/tps/i2/T1je8uXEBgXXagEfc2-10-205.png") no-repeat scroll 0 0 rgba(0, 0, 0, 0);
            display: inline;
            float: left;
            height: 205px;
            margin: 24px 0 0 8px;
            overflow: hidden;
            width: 10px;
        }
        .tao-inner-content {
            background: url("http://img03.taobaocdn.com/tps/i3/T16VXtXBNiXXXPeW.X-519-190.png") no-repeat scroll 0 0 rgba(0, 0, 0, 0);
            display: inline;
            float: left;
            height: 190px;
            margin: 0 0 0 20px;
            overflow: hidden;
            width: 519px;
        }
        .tao-inner-block {
            height: 130px;
            margin: 30px 0 0 40px;
            overflow: hidden;
            width: 450px;
        }
        .tao-inner-block .inner-left {
            float: left;
            height: 130px;
            overflow: hidden;
            width: 230px;
        }
        .inner-left .alink {
            display: block;
            height: 130px;
            overflow: hidden;
            position: relative;
            width: 230px;
        }
        .inner-left .alink img {
            display: block;
            height: 130px;
            width: 230px;
        }
        .tao-inner-block .icon-player {
            background: url("http://img02.taobaocdn.com/tps/i2/T1J5FFXy8cXXaiphQj-60-145.png") no-repeat scroll 0 -40px rgba(0, 0, 0, 0);
            height: 50px;
            left: 10px;
            overflow: hidden;
            position: absolute;
            top: 68px;
            width: 50px;
            z-index: 10;
        }
        .inner-right {
            float: right;
            height: 130px;
            width: 202px;
        }
        .inner-date {
            color: #666666;
            font-family: "Tahoma";
        }
        .inner-title {
            height: 22px;
            line-height: 22px;
            margin-top: 5px;
            overflow: hidden;
            width: 202px;
        }
        .inner-title a {
            color: #333333;
            font-family: "Microsoft yahei";
            font-size: 18px;
            font-weight: 700;
        }
        .inner-title a:hover {
            color: #FF1155;
            text-decoration: none;
        }
        .inner-content {
            color: #999999;
            line-height: 18px;
            margin-top: 12px;
        }
        .tao-year-right {
            float: right;
            overflow: hidden;
            width: 311px;
        }
        .tao-year-right .mod-fixed {
            overflow: hidden;
            position: fixed;
            top: 0;
            width: 60px;
            z-index: 10;
        }
        .mod-timelinenav {
            margin-top: 20px;
        }
        .mod-timelinenav .yearlink {
            display: inline-block;
        }
        .mod-timelinenav a {
            display: inline-block;
        }
        .mod-timelinenav a:hover {
            text-decoration: none;
        }
        .mod-timelinenav .yearlink, .mod-timelinenav .monthlink {
            border-left: 10px solid #74C2FA;
            color: #7FCCFF;
            font-family: "Tahoma";
            line-height: 20px;
            padding-left: 8px;
        }
        .mod-timelinenav .norecord {
            display: none;
        }
        .mod-timelinenav .active .yearlink, .mod-timelinenav .active .monthlink {
            border-left: 10px solid #0099FF;
            color: #0099FF;
            font-family: "Tahoma";
            line-height: 20px;
            padding-left: 8px;
        }
        .mod-timelinenav .active .monthlink {
            color: #7FCCFF;
        }
        .mod-timelinenav .highlight .monthlink {
            color: #0099FF;
            font-family: "Tahoma";
        }
        .mod-timelinenav .active .timelinenav-mpanel {
            display: block;
        }
        .mod-timelinenav .timelinenav-mpanel {
            display: none;
        }
        .timelinenav-panel {
            overflow: hidden;
            width: 60px;
        }
        .timelinenav-panel li {
            margin: 1px 0;
        }
        .timelinenav-panel li.active, .timelinenav-panel li.active .timelinenav-mpanel li {
            margin: 0;
        }
        .hot-footage {
            bottom: 0;
            overflow: hidden;
            position: fixed;
            width: 311px;
            z-index: 8;
        }
        .hot-footage .dottle {
            border-top: 1px solid #CCCCCC;
        }
        .hot-title {
            margin-top: 12px;
        }
        .hot-icon {
            background: none repeat scroll 0 0 #FF6600;
            float: left;
            height: 28px;
            margin-top: 10px;
            overflow: hidden;
            width: 4px;
        }
        .hot-title h3 {
            color: #333333;
            font-family: "Microsoft yahei";
            font-size: 30px;
            font-weight: 500;
            padding-left: 10px;
        }
        .hot-list {
            margin-top: 5px;
            overflow: hidden;
            width: 311px;
        }
        .hot-list li {
            display: inline;
            float: left;
            height: 150px;
            margin: 5px 10px 0 0;
            overflow: hidden;
            width: 150px;
        }
        .hot-list li.last {
            margin-right: 0;
        }
        .hot-list li a {
            display: block;
            height: 100px;
            overflow: hidden;
            position: relative;
            width: 150px;
        }
        .hot-list .icon-player {
            background: url("http://img02.taobaocdn.com/tps/i2/T1J5FFXy8cXXaiphQj-60-145.png") no-repeat scroll 0 -40px rgba(0, 0, 0, 0);
            height: 50px;
            left: 10px;
            overflow: hidden;
            position: absolute;
            top: 40px;
            width: 50px;
            z-index: 10;
        }
        .hot-date {
            color: #666666;
            font-family: "Tahoma";
            height: 18px;
            line-height: 18px;
            margin-top: 5px;
        }
        .hot-desc a:hover {
            text-decoration: none;
        }
      </style>

     3. 当然更依赖于kissy哦 要引入kissy:<script src="http://a.tbcdn.cn/??s/kissy/1.2.0/kissy-min.js"></script>

     现在框架已经搭建好了,接下来我来分析下 当时我写的JS代码。首先我想渲染左侧年份列表出来 及右侧控制轴渲染出来 如下图:

     

    所以上面的代码是渲染年份列表的 如下:

    复制代码
    /* 
                 * 发jsonp请求 
                 * 1.渲染列表中的所有年份HTML出来
                 * 2.把控制轴上的所有年份及月份及条目列表中的年份渲染出来
                 */
                 S.jsonp(_config.year_url + "&timestamp="+S.now(),function(data){
                    _renderYear(data);
                 });
                 function _renderYear(data) {
                    if(data.isSuccess) {
                        var yearlists = data.list,
                            yearHTML = '',
                            liHTML = '';
                        /*
                         * 渲染列表中的所有年份HTML出来
                         */
                         for(var i = 0, ilen = yearlists.length; i < ilen; i+=1) {
                            yearHTML += '<div class="J_Year_Month">'+
                                            '<div class="tao-header-title J_Header_Title">'+
                                                '<span data-year="'+yearlists[i].year+'" class="J_Year">'+yearlists[i].year+'<i>年</i></span>'+
                                            '</div>' + 
                                            '<div class="tao-dottle-top"></div>' + 
                                            '<div class="J_Video_Block"></div>' + 
                                        '</div>';
                         }
                         var recentlyYear = yearlists[0].year;
                         D.html(D.get(_config.videoContainer),yearHTML);
                         /*
                          * 把控制轴上的所有年份渲染出来
                          */
                         for(i = 0,itemLen = yearlists.length; i < itemLen; i++){
                            liHTML += '<li data-year="'+yearlists[i].year+'" class="itemList">' + 
                                         '<a class="yearlink" href="#">'+yearlists[i].year+'年</a>' +
                                         '<ul class="timelinenav-mpanel"></ul>' +  
                                       '</li>';
                         }
                         D.html(D.get(_config.listContainer),liHTML,false,function(){
                            D.addClass(D.get(_config.listContainer + " li"),_config.activeCls);
                            D.attr(D.get(_config.listContainer + " li"),{"index":"1"});
                         });
    
                         /*
                          * 分别渲染各个年份中的月份
                          */
                         var monthContainers = D.query(".timelinenav-mpanel"); 
                         for(var m = 0, mlen = monthContainers.length; m < mlen; m+=1) {
                            var ulHTML = "";
                            for(var k = 0,subItems = yearlists[m].month.length; k < subItems; k+=1){
                                ulHTML += '<li data-year="'+yearlists[m].year+'" data-month="'+yearlists[m].month[k]+'" class="itemHover">' + 
                                             '<a class="monthlink" href="#">'+yearlists[m].month[k]+'月</a>' +
                                           '</li>';
                            }
                            D.html(monthContainers[m],ulHTML,false,function(){
                                
                                var headerTitle = D.query(".J_Year"),
                                    itemLists = D.query(".itemList"),
                                    videoBlocks = D.query(".J_Video_Block");
                                // 默认时候 当前年份 最近月份高亮
                                D.addClass(D.get(".itemHover"),_config.highlightCls);
                            });
                         }
    复制代码

    4. 接着发请求 把左侧列表中最近年份 下的所有月份渲染出来 如下代码可以实现:

    复制代码
    var self = this,
                    _config = self.config;
                var allYears = D.query(".J_Year_Month");
                
                S.each(allYears,function(everyYear,index){
                    var jYear = D.get(".J_Year",everyYear),
                        jDataYear = D.attr(jYear,"data-year"),
                        jTextArea = D.get(".J_Video_Block",everyYear);
                    S.jsonp(_config.list_url+"&group="+jDataYear+"&timestamp="+S.now(),function(data){
                        if(data.isSuccess){
                            var dataLists = data.list,
                                dataContainer = "";
                            for(var x=0,xlen=dataLists.length; x<xlen; x+=1){
                                var tempGroupId = dataLists[x].group_id;
                                dataContainer +='<div class="tao-video-content">'+
                                                    '<div class="addBlock"></div>' +
                                                    '<div class="left-date" videoMonth="'+tempGroupId.substring(4,6)+'">'+
                                                        '<span><i class="J_Month" M_year="'+tempGroupId.substring(0,4)+'">'+tempGroupId.substring(4,6)+'</i>月</span>'+
                                                        '<span><i class="J_Day">'+tempGroupId.substring(6,8)+'</i>日</span>'+
                                                    '</div>'+
                                                    '<div class="tao-line"></div>'+
                                                    '<div class="tao-inner-content">'+
                                                        '<div class="tao-inner-block">'+
                                                            '<div class="inner-left">'+
                                                                '<a href="http://bbs.hitao.com/apps.php?q=tvshow&m=detail_new&tid='+dataLists[x].tid+'" class="alink">'+
                                                                    '<img src="'+dataLists[x].video_pic.replace("/0","/1")+'" alt="">'+
                                                                    '<span class="icon-player"></span>'+
                                                                '</a>'+
                                                            '</div>'+
                                                            '<div class="inner-right">'+
                                                                '<p class="inner-date">'+tempGroupId.substring(0,4)+'-'+tempGroupId.substring(4,6)+'-'+tempGroupId.substring(6,8)+'</p>'+
                                                                '<p class="inner-title">' +
                                                                    '<a href="http://bbs.hitao.com/apps.php?q=tvshow&m=detail_new&tid='+dataLists[x].tid+'">'+dataLists[x].subject+'</a>'+
                                                                '</p>'+
                                                                '<div class="inner-content">'+dataLists[x].content+'</div>'+
                                                            '</div>'+
                                                        '</div>'+
                                                    '</div>'+
                                                 '</div>';
                            }
                            if(flag == 'hover') {
                                (new DataLazyload(everyYear, {diff: 200})).addCallback(everyYear, function(){
                                    self._isDelayLoad(jTextArea,dataContainer,index);
                                });
                            }
    复制代码

    我上面的代码也有个小缺点 就是说页面一打开的时候 联系发了四个请求 把所有年份都渲染出来 但是数据并没有到页面上来 还是以前的逻辑 当滚动条滚动到离还有200像素的时候 再把数据渲染到页面上来。

    5. 接着再做了以下事情:

         1.  列表中的年份和控制轴中的年份相等时候 控制轴的年份展开。

       2.  当滚动到列表中年份中的月份时候 对应的控制轴月份也要相应的变化(如高亮等),随着鼠标滚动。

       3.  点击控制轴任一年份时候 滚动到条目列表中相对应的年份来.

    代码如下:

       

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    var self = this,
                    _config = self.config,
                    _cache = self.cache;
     
                D.html(jTextArea,dataContainer,false,function(){
                    var itemLists = D.query(_config.listContainer + " .itemList"),
                        itemHover = D.query(".itemHover",itemLists[index]),
                        jmonths = D.query(".J_Month",jTextArea[index]),
                        headerTitle = D.query(".J_Year");
                    // 默认时候 当前年份 最近月份高亮
                    D.addClass(D.get(".itemHover"),_config.highlightCls);
         
                    var storage = function(itemFChar){
                        for(var i = 0, ilen = itemHover.length; i < ilen; i+=1){
                             var itemMonth = D.attr(itemHover[i],"data-month");
                             if(itemMonth == itemFChar){
                                KISSY.all(itemHover[i]).addClass(_config.highlightCls).siblings().removeClass(_config.highlightCls);
                            }
                        }
                    };
                    E.on(window,'scroll',function(){
                        if(D.hasClass(D.get(_config.listContainer),'isScroll')){
                            var wTop = D.offset(window).top;
                            /*** 列表中的年份和控制轴中的年份相等时候 控制轴的年份展开 ***/
                            for(var m=0,mlen=headerTitle.length; m<mlen; m+=1){
                                var headerTop = D.offset(headerTitle[m]).top,
                                    headAttr = D.attr(headerTitle[m],"data-year"),
                                    itemAttr = D.attr(itemLists[m],"data-year");
                                if(headerTop <= wTop){
                                    if(headAttr == itemAttr){
                                        KISSY.all(itemLists[m]).addClass(_config.activeCls).siblings().removeClass(_config.activeCls);
                                    }
                                }
                            }
                            /*** 当滚动到列表中年份中的月份时候 对应的控制轴月份也要相应的变化(如高亮等) **/
                            for(var nn = 0, nlen = jmonths.length; nn < nlen; nn+=1){
                                var jmonthTop = D.offset(jmonths[nn]).top;
                                if(jmonthTop <= wTop){
                                     
                                    var itemVal = D.html(jmonths[nn]),
                                    // 转换02 -> 2
                                    itemFChar = itemVal.substring(0,1);
                                    if(itemFChar == 0){
                                        itemFChar = itemVal.substring(1,2);
                                    }else{
                                        itemFChar = itemVal.substring(0,2);
                                    }
                                    storage(itemFChar);
                                }
                            }
                        }
                    });
                    // 点击控制轴任一年份时候 滚动到条目列表中相对应的年份来
                   var  itemLists = D.query(_config.listContainer + " .itemList");
                   S.each(itemLists,function(item,index){
                       var innerIndex;
                       E.on(item,'click',function(e){
                           e.preventDefault();
                           e.halt();
                           innerIndex = index;
                           var scrollTimer,
                               DELAY = 0.3;
                           !D.hasClass(KISSY.all(this),_config.activeCls) && KISSY.all(this).addClass(_config.activeCls).siblings().removeClass(_config.activeCls);
                            
                           if(!D.hasClass(KISSY.all(this),"isClick")){
                               D.addClass(KISSY.all(this),"isClick");
                           }
                           var curThis = KISSY.all(this);
                           // 删除类
                           D.hasClass(D.get(_config.listContainer),'isScroll') && D.removeClass(D.get(_config.listContainer),'isScroll');
                           var headerTop = D.offset(headerTitle[index]).top;
                           scrollTimer && scrollTimer.cancel();
                           scrollTimer = S.later(function(){
                                KISSY.all("html,body").animate({"scrollTop":headerTop},DELAY,'easeBothStrong',function(){
                                    D.removeClass(D.query(".itemHover"),_config.highlightCls);
                                    !D.hasClass(D.get(".itemHover",curThis),_config.highlightCls) && D.addClass(D.get(".itemHover",curThis),_config.highlightCls);
                                    !D.hasClass(D.get(_config.listContainer),'isScroll') && D.addClass(D.get(_config.listContainer),'isScroll');
                                });
                            },DELAY);
                            _config.yearCallback && S.isFunction(_config.yearCallback) && _config.yearCallback();
                            self._clickMenu(itemLists,innerIndex);
                       });
                       if(innerIndex == undefined){
                          innerIndex = 0;
                          self._clickMenu(itemLists,innerIndex);
                       }
                   });

     6. 最后 点击控制轴当前年份中的月份时候 滚动到当前的月份的地方。代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    // 点击控制轴当前年份中的月份时候 滚动到当前的月份的地方。
                var itemHovers = D.query(".itemHover",KISSY.all(itemLists[innerIndex]));
                S.each(itemHovers,function(itemHover,curIndex){
                    E.on(itemHover,'click',function(e){
                         
                        e.halt();
                        var itemMonth = D.attr(KISSY.all(itemHover),"data-month");
                        var tempArr = [],
                            scrollTimer,
                            DELAY = 0.1;
                        console.log(itemMonth);
                        var curMonths = D.query(".left-date",D.query(".J_Year_Month")[innerIndex]);
                         // 删除类
                        D.hasClass(D.get(_config.listContainer),'isScroll') && D.removeClass(D.get(_config.listContainer),'isScroll');
                        KISSY.all('.itemHover').removeClass(_config.highlightCls);
                        KISSY.all(this).addClass(_config.highlightCls).siblings().removeClass(_config.highlightCls);
                        for(var i=0; i<curMonths.length; i+=1){
                            var itemVal = D.attr(curMonths[i],"videoMonth");
                            // 转换02 -> 2
                            var itemFChar = itemVal.substring(0,1);
                            if(itemFChar == 0){
                                itemFChar = itemVal.substring(1,2);
                            }else{
                                itemFChar = itemVal.substring(0,2);
                            }
                            tempArr.push(itemFChar);
                        }
                        for(var j=0; j<tempArr.length; j+=1){
                            var tempV = tempArr[j];
                            if(itemMonth == tempArr[j]){
                                var mtop = D.offset(curMonths[j]).top;
                                scrollTimer && scrollTimer.cancel();
                                scrollTimer = S.later(function(){
                                    KISSY.all("html,body").animate({"scrollTop":mtop},DELAY,'easeBothStrong',function(){
                                        !D.hasClass(D.get(_config.listContainer),'isScroll') && D.addClass(D.get(_config.listContainer),'isScroll');
                                    });
                                },DELAY);
                                break; // 此break是当数组里面的月份有多个相同的时候 只取第一个月份
                            }
                        }
                        _config.monthCallback && S.isFunction(_config.monthCallback) && _config.monthCallback();

      综合以上 所有JS代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    KISSY.add('timeline/nav',function(S,DataLazyload){
        var D = S.DOM,
            E = S.Event;
     
        function TimeLineNav() {
     
            this.config = {
                year_url       :'http://bbs.hitao.com/apps.php?q=tvshow&m=video_years',    //所有年份URL
                list_url       :'http://bbs.hitao.com/apps.php?q=tvshow&m=video_group',    // 时间轴list列表 URL
                delay          : 100,                                                      // 延迟time
                highlightCls   :'highlight',                                               // 高亮类
                fixedCls       :'mod-fixed',                                               // fixed类
                activeCls      :'active',                                                  // 当前active class
                videoContainer :'#J_Video_Left',                                           // 左侧视频容器
                listContainer  :'#timelinenavpanel',                                       // 控制轴容器
                yearCallback   : null,                                                     // 点击某一项年份时的回调函数
                monthCallBack  : null                                                      // 点击某一项月份时候回调
            };
     
            this.cache = {
                 
            };
        }
        TimeLineNav.prototype = {
            init: function(options) {
                this.config = S.augment(this.config,options || {});
                var self = this,
                    _config = self.config;
                /*
                 * 发jsonp请求
                 * 1.渲染列表中的所有年份HTML出来
                 * 2.把控制轴上的所有年份及月份及条目列表中的年份渲染出来
                 */
                 S.jsonp(_config.year_url + "&timestamp="+S.now(),function(data){
                    _renderYear(data);
                 });
                 function _renderYear(data) {
                    if(data.isSuccess) {
                        var yearlists = data.list,
                            yearHTML = '',
                            liHTML = '';
                        /*
                         * 渲染列表中的所有年份HTML出来
                         */
                         for(var i = 0, ilen = yearlists.length; i < ilen; i+=1) {
                            yearHTML += '<div class="J_Year_Month">'+
                                            '<div class="tao-header-title J_Header_Title">'+
                                                '<span data-year="'+yearlists[i].year+'" class="J_Year">'+yearlists[i].year+'<i>年</i></span>'+
                                            '</div>' +
                                            '<div class="tao-dottle-top"></div>' +
                                            '<div class="J_Video_Block"></div>' +
                                        '</div>';
                         }
                         var recentlyYear = yearlists[0].year;
                         D.html(D.get(_config.videoContainer),yearHTML);
                         /*
                          * 把控制轴上的所有年份渲染出来
                          */
                         for(i = 0,itemLen = yearlists.length; i < itemLen; i++){
                            liHTML += '<li data-year="'+yearlists[i].year+'" class="itemList">' +
                                         '<a class="yearlink" href="#">'+yearlists[i].year+'年</a>' +
                                         '<ul class="timelinenav-mpanel"></ul>'
                                       '</li>';
                         }
                         D.html(D.get(_config.listContainer),liHTML,false,function(){
                            D.addClass(D.get(_config.listContainer + " li"),_config.activeCls);
                            D.attr(D.get(_config.listContainer + " li"),{"index":"1"});
                         });
     
                         /*
                          * 分别渲染各个年份中的月份
                          */
                         var monthContainers = D.query(".timelinenav-mpanel");
                         for(var m = 0, mlen = monthContainers.length; m < mlen; m+=1) {
                            var ulHTML = "";
                            for(var k = 0,subItems = yearlists[m].month.length; k < subItems; k+=1){
                                ulHTML += '<li data-year="'+yearlists[m].year+'" data-month="'+yearlists[m].month[k]+'" class="itemHover">' +
                                             '<a class="monthlink" href="#">'+yearlists[m].month[k]+'月</a>' +
                                           '</li>';
                            }
                            D.html(monthContainers[m],ulHTML,false,function(){
                                 
                                var headerTitle = D.query(".J_Year"),
                                    itemLists = D.query(".itemList"),
                                    videoBlocks = D.query(".J_Video_Block");
                                // 默认时候 当前年份 最近月份高亮
                                D.addClass(D.get(".itemHover"),_config.highlightCls);
                            });
                         }
                          
                        self._query('hover');
                    }else {
                        return;
                    }
                 }
                /*
                 * 1.滚动条先滚动 当离顶部距离差距不大的时候 使右侧菜单固定在顶部20px;
                 */
                var timelineTop = D.offset(".mod-timelinenav").top,
                    scrollTimer;
                E.on(window,'scroll',function(){
                    scrollTimer && scrollTimer.cancel();
                    scrollTimer = S.later(function(){
                        var windowTop = D.offset(window).top;
                        if(timelineTop <=windowTop){
                            D.addClass(".mod-timelinenav","mod-fixed");
                        }else{
                            D.removeClass(".mod-timelinenav","mod-fixed");
                        }
                    },_config.delay);
                });
                 
            },
            _query: function(flag) {
                var self = this,
                    _config = self.config;
                var allYears = D.query(".J_Year_Month");
                 
                S.each(allYears,function(everyYear,index){
                    var jYear = D.get(".J_Year",everyYear),
                        jDataYear = D.attr(jYear,"data-year"),
                        jTextArea = D.get(".J_Video_Block",everyYear);
                    S.jsonp(_config.list_url+"&group="+jDataYear+"&timestamp="+S.now(),function(data){
                        if(data.isSuccess){
                            var dataLists = data.list,
                                dataContainer = "";
                            for(var x=0,xlen=dataLists.length; x<xlen; x+=1){
                                var tempGroupId = dataLists[x].group_id;
                                dataContainer +='<div class="tao-video-content">'+
                                                    '<div class="addBlock"></div>' +
                                                    '<div class="left-date" videoMonth="'+tempGroupId.substring(4,6)+'">'+
                                                        '<span><i class="J_Month" M_year="'+tempGroupId.substring(0,4)+'">'+tempGroupId.substring(4,6)+'</i>月</span>'+
                                                        '<span><i class="J_Day">'+tempGroupId.substring(6,8)+'</i>日</span>'+
                                                    '</div>'+
                                                    '<div class="tao-line"></div>'+
                                                    '<div class="tao-inner-content">'+
                                                        '<div class="tao-inner-block">'+
                                                            '<div class="inner-left">'+
                                                                '<a href="http://bbs.hitao.com/apps.php?q=tvshow&m=detail_new&tid='+dataLists[x].tid+'" class="alink">'+
                                                                    '<img src="'+dataLists[x].video_pic.replace("/0","/1")+'" alt="">'+
                                                                    '<span class="icon-player"></span>'+
                                                                '</a>'+
                                                            '</div>'+
                                                            '<div class="inner-right">'+
                                                                '<p class="inner-date">'+tempGroupId.substring(0,4)+'-'+tempGroupId.substring(4,6)+'-'+tempGroupId.substring(6,8)+'</p>'+
                                                                '<p class="inner-title">' +
                                                                    '<a href="http://bbs.hitao.com/apps.php?q=tvshow&m=detail_new&tid='+dataLists[x].tid+'">'+dataLists[x].subject+'</a>'+
                                                                '</p>'+
                                                                '<div class="inner-content">'+dataLists[x].content+'</div>'+
                                                            '</div>'+
                                                        '</div>'+
                                                    '</div>'+
                                                 '</div>';
                            }
                            if(flag == 'hover') {
                                (new DataLazyload(everyYear, {diff: 200})).addCallback(everyYear, function(){
                                    self._isDelayLoad(jTextArea,dataContainer,index);
                                });
                            }
                        }else {
                            return;
                        }
                    });
                     
                });
            },
            _isDelayLoad: function(jTextArea,dataContainer,index) {
                var self = this,
                    _config = self.config,
                    _cache = self.cache;
     
                D.html(jTextArea,dataContainer,false,function(){
                    var itemLists = D.query(_config.listContainer + " .itemList"),
                        itemHover = D.query(".itemHover",itemLists[index]),
                        jmonths = D.query(".J_Month",jTextArea[index]),
                        headerTitle = D.query(".J_Year");
                    // 默认时候 当前年份 最近月份高亮
                    D.addClass(D.get(".itemHover"),_config.highlightCls);
         
                    var storage = function(itemFChar){
                        for(var i = 0, ilen = itemHover.length; i < ilen; i+=1){
                             var itemMonth = D.attr(itemHover[i],"data-month");
                             if(itemMonth == itemFChar){
                                KISSY.all(itemHover[i]).addClass(_config.highlightCls).siblings().removeClass(_config.highlightCls);
                            }
                        }
                    };
                    E.on(window,'scroll',function(){
                        if(D.hasClass(D.get(_config.listContainer),'isScroll')){
                            var wTop = D.offset(window).top;
                            /*** 列表中的年份和控制轴中的年份相等时候 控制轴的年份展开 ***/
                            for(var m=0,mlen=headerTitle.length; m<mlen; m+=1){
                                var headerTop = D.offset(headerTitle[m]).top,
                                    headAttr = D.attr(headerTitle[m],"data-year"),
                                    itemAttr = D.attr(itemLists[m],"data-year");
                                if(headerTop <= wTop){
                                    if(headAttr == itemAttr){
                                        KISSY.all(itemLists[m]).addClass(_config.activeCls).siblings().removeClass(_config.activeCls);
                                    }
                                }
                            }
                            /*** 当滚动到列表中年份中的月份时候 对应的控制轴月份也要相应的变化(如高亮等) **/
                            for(var nn = 0, nlen = jmonths.length; nn < nlen; nn+=1){
                                var jmonthTop = D.offset(jmonths[nn]).top;
                                if(jmonthTop <= wTop){
                                     
                                    var itemVal = D.html(jmonths[nn]),
                                    // 转换02 -> 2
                                    itemFChar = itemVal.substring(0,1);
                                    if(itemFChar == 0){
                                        itemFChar = itemVal.substring(1,2);
                                    }else{
                                        itemFChar = itemVal.substring(0,2);
                                    }
                                    storage(itemFChar);
                                }
                            }
                        }
                    });
                    // 点击控制轴任一年份时候 滚动到条目列表中相对应的年份来
                   var  itemLists = D.query(_config.listContainer + " .itemList");
                   S.each(itemLists,function(item,index){
                       var innerIndex;
                       E.on(item,'click',function(e){
                           e.preventDefault();
                           e.halt();
                           innerIndex = index;
                           var scrollTimer,
                               DELAY = 0.3;
                           !D.hasClass(KISSY.all(this),_config.activeCls) && KISSY.all(this).addClass(_config.activeCls).siblings().removeClass(_config.activeCls);
                            
                           if(!D.hasClass(KISSY.all(this),"isClick")){
                               D.addClass(KISSY.all(this),"isClick");
                           }
                           var curThis = KISSY.all(this);
                           // 删除类
                           D.hasClass(D.get(_config.listContainer),'isScroll') && D.removeClass(D.get(_config.listContainer),'isScroll');
                           var headerTop = D.offset(headerTitle[index]).top;
                           scrollTimer && scrollTimer.cancel();
                           scrollTimer = S.later(function(){
                                KISSY.all("html,body").animate({"scrollTop":headerTop},DELAY,'easeBothStrong',function(){
                                    D.removeClass(D.query(".itemHover"),_config.highlightCls);
                                    !D.hasClass(D.get(".itemHover",curThis),_config.highlightCls) && D.addClass(D.get(".itemHover",curThis),_config.highlightCls);
                                    !D.hasClass(D.get(_config.listContainer),'isScroll') && D.addClass(D.get(_config.listContainer),'isScroll');
                                });
                            },DELAY);
                            _config.yearCallback && S.isFunction(_config.yearCallback) && _config.yearCallback();
                            self._clickMenu(itemLists,innerIndex);
                       });
                       if(innerIndex == undefined){
                          innerIndex = 0;
                          self._clickMenu(itemLists,innerIndex);
                       }
                   }); 
                });
            },
            _clickMenu: function(itemLists,innerIndex) {
                var self = this,
                    _config = self.config;
                if(innerIndex == undefined){
                    return;
                }
                // 点击控制轴当前年份中的月份时候 滚动到当前的月份的地方。
                var itemHovers = D.query(".itemHover",KISSY.all(itemLists[innerIndex]));
                S.each(itemHovers,function(itemHover,curIndex){
                    E.on(itemHover,'click',function(e){
                         
                        e.halt();
                        var itemMonth = D.attr(KISSY.all(itemHover),"data-month");
                        var tempArr = [],
                            scrollTimer,
                            DELAY = 0.1;
                        console.log(itemMonth);
                        var curMonths = D.query(".left-date",D.query(".J_Year_Month")[innerIndex]);
                         // 删除类
                        D.hasClass(D.get(_config.listContainer),'isScroll') && D.removeClass(D.get(_config.listContainer),'isScroll');
                        KISSY.all('.itemHover').removeClass(_config.highlightCls);
                        KISSY.all(this).addClass(_config.highlightCls).siblings().removeClass(_config.highlightCls);
                        for(var i=0; i<curMonths.length; i+=1){
                            var itemVal = D.attr(curMonths[i],"videoMonth");
                            // 转换02 -> 2
                            var itemFChar = itemVal.substring(0,1);
                            if(itemFChar == 0){
                                itemFChar = itemVal.substring(1,2);
                            }else{
                                itemFChar = itemVal.substring(0,2);
                            }
                            tempArr.push(itemFChar);
                        }
                        for(var j=0; j<tempArr.length; j+=1){
                            var tempV = tempArr[j];
                            if(itemMonth == tempArr[j]){
                                var mtop = D.offset(curMonths[j]).top;
                                scrollTimer && scrollTimer.cancel();
                                scrollTimer = S.later(function(){
                                    KISSY.all("html,body").animate({"scrollTop":mtop},DELAY,'easeBothStrong',function(){
                                        !D.hasClass(D.get(_config.listContainer),'isScroll') && D.addClass(D.get(_config.listContainer),'isScroll');
                                    });
                                },DELAY);
                                break; // 此break是当数组里面的月份有多个相同的时候 只取第一个月份
                            }
                        }
                        _config.monthCallback && S.isFunction(_config.monthCallback) && _config.monthCallback();
                    });
                });
            }
        };
     
        return TimeLineNav;
    },{requires:['datalazyload']});

      JS初始化如下 :
      KISSY.use("timeline/nav",function(S,obj){
           new obj().init({});
     });

    转载自:http://www.cnblogs.com/tugenhua0707/

  • 相关阅读:
    简单查询plan
    EXP AND IMP
    (4.16)sql server迁移DB文件(同一DB内)
    sql server日志传送实践(基于server 2008 R2)
    (1.3)学习笔记之mysql体系结构(C/S整体架构、内存结构、物理存储结构、逻辑结构、SQL查询流程)
    (1.2)学习笔记之mysql体系结构(数据库文件)
    (1.1)学习笔记之mysql体系结构(内存、进程、线程)
    SSAS(SQL Server 分析服务)、***S(SQL Server报表服务)、SSIS(SQL Server集成服务)
    教你使用SQL查询(1-12)
    Sql Server内置函数实现MD5加密
  • 原文地址:https://www.cnblogs.com/lzbk/p/6330525.html
Copyright © 2020-2023  润新知