zoukankan      html  css  js  c++  java
  • JS时间轴效果(类似于qq空间时间轴效果)

           在上一家公司写了一个时间轴效果,今天整理了下,感觉有必要写一篇博客出来 给大家分享分享 当然代码还有很多不足的地方,希望大家多指点指点下,此效果类似于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代码 如下:

    <style>
    	 .tao-allMonth-w990 { 990px;margin: 100px auto 0;overflow: hidden;	}
    	.tao-video-left {float:left; 620px;overflow: hidden;}
    	.tao-video-block { 620px;overflow: hidden;}
    	.tao-header-title { 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 { 10px;height: 40px;margin-left: 68px;background: none repeat scroll 0 0 #FFCC99;overflow: hidden;	}
    	.tao-video-content {position: relative; 620px;overflow: hidden;}
    	.tao-video-content .addBlock {
    		background: none repeat scroll 0 0 #FFCC99;
    		height: 16px;
    		left: 68px;
    		position: absolute;
    		 10px;
    	}
    	.left-date {
    		color: #FF6600;
    		float: left;
    		font-family: "Microsoft yahei";
    		font-size: 14px;
    		height: 20px;
    		line-height: 20px;
    		margin-top: 18px;
    		overflow: hidden;
    		 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;
    		 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;
    		 519px;
    	}
    	.tao-inner-block {
    		height: 130px;
    		margin: 30px 0 0 40px;
    		overflow: hidden;
    		 450px;
    	}
    	.tao-inner-block .inner-left {
    		float: left;
    		height: 130px;
    		overflow: hidden;
    		 230px;
    	}
    	.inner-left .alink {
    		display: block;
    		height: 130px;
    		overflow: hidden;
    		position: relative;
    		 230px;
    	}
    	.inner-left .alink img {
    		display: block;
    		height: 130px;
    		 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;
    		 50px;
    		z-index: 10;
    	}
    	.inner-right {
    		float: right;
    		height: 130px;
    		 202px;
    	}
    	.inner-date {
    		color: #666666;
    		font-family: "Tahoma";
    	}
    	.inner-title {
    		height: 22px;
    		line-height: 22px;
    		margin-top: 5px;
    		overflow: hidden;
    		 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;
    		 311px;
    	}
    	.tao-year-right .mod-fixed {
    		overflow: hidden;
    		position: fixed;
    		top: 0;
    		 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;
    		 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;
    		 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;
    		 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;
    		 311px;
    	}
    	.hot-list li {
    		display: inline;
    		float: left;
    		height: 150px;
    		margin: 5px 10px 0 0;
    		overflow: hidden;
    		 150px;
    	}
    	.hot-list li.last {
    		margin-right: 0;
    	}
    	.hot-list li a {
    		display: block;
    		height: 100px;
    		overflow: hidden;
    		position: relative;
    		 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;
    		 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.  点击控制轴任一年份时候 滚动到条目列表中相对应的年份来.

    代码如下:

       

    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. 最后 点击控制轴当前年份中的月份时候 滚动到当前的月份的地方。代码如下:

    // 点击控制轴当前年份中的月份时候 滚动到当前的月份的地方。
    		    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代码如下:

    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({});
     });

  • 相关阅读:
    Numpy基础学习笔记3
    Numpy基础学习笔记2
    Halcon学习笔记——机器视觉应用工程开发思路及相机标定
    WPF的依赖项属性
    如何理解委托与事件
    LINQ和.NET数据访问
    PLC通信网络
    运动控制基础
    PLC总结
    C#使用第三方组件Epplus操作Excel表
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/3407741.html
Copyright © 2011-2022 走看看