时间插件(选择日,周,月)

/*
AUTHOR : ELEANOR MAO
EMAIL : danningmao@outlook.com
2016-02-5
*/
+(function($){
	'use strict';

	//↓可选参数
	var CALENDAR_OPTION = {
		type : 'normal',//'normal','weekly','monthly'
		id : '',//日历的id
		className : '',//日历的样式
		dayNames : ['日', '一', '二', '三', '四', '五', '六'],//周名
		numbers : ['一', '二', '三', '四', '五', '六'],//数字标示
		today : true,//是否标志今天
		select : true,//是否单击选中
		multi : false,//是否单击可多选
		disOtherMonth : false,//其他月日期是否可选
		setMonth : null,//设定月
		setYear : null,//设定年
		selectDate : null, //format 'yyyy-mm-dd' or 'yyyy-mm-weekn' every element can be set to 'each';
		allowDate : null, //format [yyyy-mm-dd,yyyy-mm-dd]
		prev: 'icon-arrow-left',//向前的按钮
		next: 'icon-arrow-right',//向后的按钮
		onselect: function(){},//当选中的回调函数
		ongoprev: function(){},//当往前翻的回调函数
		ongonext: function(){} //当往后翻的回调函数
	}

	var Calendar = function( element, options){
		this.el = $(element);
		this.opt = null;
		this.date = null;
		this.type = null;
		this.calendar = '';

		this.init(element, options);
	}

	Calendar.prototype.init = function(element, options){
		this.date = this.getDate();
		var options = this.opt = this.getOptions( options, this.date );
		this.type = options.type;
		options.target = $(element);
		this.calendar = '<table class="flexoCalendar '+ options.className +'"  id="'+ options.id +'" cellspacing="0">';
		this.calendar += this.bulidCH(options);
		if( this.type == 'normal' ){
			this.calendar += this.bulidWeekBar(options);
			this.calendar += '</thead>';
			this.calendar += '<tbody>';
			this.calendar += this.bulidFull(options);
		}
		else if(this.type == 'weekly' ){
			this.calendar += '</thead><tbody>';
			this.calendar += this.bulidWeekly(options);
		} 
		else if(this.type == 'monthly' ){
			this.calendar += '</thead><tbody>';
			this.calendar += this.bulidMonthly(options);
		}
		this.calendar +='</tbody></table>';
		$(element).append(this.calendar).trigger('click');

		$(element).on('click', ".prev, .next", options, function(){
			var month = $(this).data('month').split('-')[1];
			var year = $(this).data('month').split('-')[0];
			var allowDate = options.allowDate;
			var calendar = '';
			if ( $.isArray(allowDate) && (( year == allowDate[0].split('-')[0] && month == allowDate[0].split('-')[1] ) || ( year == allowDate[1].split('-')[0] && month == allowDate[1].split('-')[1])) ) return;
			if(options.type == 'normal'){
				calendar = Calendar.prototype.bulidFull(options, year, month);
			}
			else if(options.type == 'monthly'){
				calendar = Calendar.prototype.bulidMonthly(options, year, month);
			}
			else if(options.type == 'weekly'){
				calendar = Calendar.prototype.bulidWeekly(options, year, month);
			}
			$(options.target).find('table.flexoCalendar tbody').empty().append(calendar).trigger('el.create');			
			Calendar.prototype.changeCH(this,options);

			if( this.className == 'prev' && options.ongoprev ){
				options.ongoprev.call(options.target, $(this).next('.current-year').data('year'), $(this).data('month'));
			}
			if( this.className == 'next' && options.ongonext ){
				options.ongonext.call(options.target, $(this).next('.current-year').data('year'), $(this).data('month'));
			}

		})

		if( options.select ){
			$(element).on('click', 'table>tbody>tr>td', options, function(){
				if( !options.multi ){
					$(this).parents("tbody").find("td.selected").removeClass('selected');
				}

				if( options.disOtherMonth ){
					if( this.className.split(' ')[0] != 'other-month'){ $(this).addClass('selected'); };
				}
				else{
					$(this).addClass('selected');
				}

				if( options.onselect ){
					options.onselect.call(options.target, $(this).data('time'));
				}
			})
		}
		
	}

	Calendar.prototype.bulidCH = function(options){
		var calendar='';
		var year = options.setYear;
		var month = options.setMonth;
		var prevdate = this.getPrev(year, month, this.type);
		var nextdate = this.getNext(year, month, this.type);
		var prev = options.prev;
		var next = options.next; 
		if( this.type == 'normal' ){
			calendar +='<thead><tr class="calendar-hd"><th class="prev" data-month="'+prevdate+'"><i class="'+prev+'"></i></th><th class="current-year" data-year="'+year+'-'+this.dispose(month)+'" colspan="5">'+year+'年'+this.dispose(month)+'月</th><th class="next" data-month="'+nextdate+'"><i class="'+next+'"></i></th></tr>';
		}
		else if(this.type == 'weekly' ){
			var prevMonth = prevdate.split('-')[1];
			var prevYear = prevdate.split('-')[0];
			var nextMonth = nextdate.split('-')[1];
			var nextYear = nextdate.split('-')[0];
			var prevWeek = this.forWeek(prevYear ,prevMonth);
			var nextWeek = this.forWeek(nextYear ,nextMonth);
			calendar +='<thead><tr class="calendar-hd"><th class="prev" data-month="'+prevdate+'" data-week="'+prevWeek+'"><i class="'+prev+'"></i></th><th class="current-year" data-year="'+year+'-'+this.dispose(month)+'" colspan="5">'+year+'年'+this.dispose(month)+'月</th><th class="next" data-month="'+nextdate+'" data-week="'+nextWeek+'"><i class="'+next+'"></i></th></tr></thead>';
		} 
		else if(this.type == 'monthly' ){
			calendar +='<thead><tr class="calendar-hd"><th class="prev" data-month="'+prevdate+'" colspan="2"><i class="'+prev+'"></i></th><th class="current-year" data-year="'+year+'-'+this.dispose(month)+'" colspan="4">'+year+'年</th><th class="next" data-month="'+nextdate+'" colspan="2"><i class="'+next+'"></i></th></tr></thead>';
		}

		return calendar;
	}

	Calendar.prototype.changeCH = function(element,options){
		var month = $(element).data('month').split('-')[1];
		var year = $(element).data('month').split('-')[0];
		month = parseInt(month);
		year = parseInt(year);
		var type = options.type;
		var prevdate = this.getPrev(year, month, type);
		var nextdate = this.getNext(year, month, type);
		var crtdate = year + '-' + this.dispose(month);
		var header = $(options.target).find(".current-year");
		if(type == 'weekly'){
			var prevMonth = prevdate.split('-')[1];
			var prevYear = prevdate.split('-')[0];
			var nextMonth = nextdate.split('-')[1];
			var nextYear = nextdate.split('-')[0];
			var prevWeek = this.forWeek(prevYear ,prevMonth);
			var nextWeek = this.forWeek(nextYear ,nextMonth);
			$(options.target).find(".prev").data('month', prevdate).attr('data-month', prevdate).data('week', prevWeek).attr('data-week', prevWeek);
			$(options.target).find(".next").data('month', nextdate).attr('data-month', nextdate).data('week', nextWeek).attr('data-week', nextWeek);
		}else{
			$(options.target).find(".prev").data('month', prevdate).attr('data-month', prevdate);
			$(options.target).find(".next").data('month', nextdate).attr('data-month', nextdate);
		}

		$(options.target).find(".current-year").data('year', crtdate).attr('data-year', crtdate);

		if(type == 'monthly' ){
			header.text(year+'年');
		}else{
			header.text(year+'年'+ this.dispose(month) +'月');
		}
	}

	Calendar.prototype.bulidWeekBar = function(options){
		var calendar = '<tr class="weekday">';
		for(var i = 0; i < 7; i++){
			calendar += '<th data-day=day'+i+'>'+options.dayNames[i]+'</th>';
		}
		calendar += '</tr></thead>';
		return calendar;
	}

	Calendar.prototype.bulidFull = function(options, year, month){
		var calendar = '';
		var month = month ? parseInt(month) : parseInt(options.setMonth);
		var year = year ? parseInt(year) : parseInt(options.setYear);
		var prevdate = this.getPrev(year, month, 'normal');
		var nextdate = this.getNext(year, month, 'normal');
		var monthLen = eli.getMonthLen(year, month);
		var prevMonthLen = eli.getMonthLen(prevdate.split('-')[0], prevdate.split('-')[1]);
		var firDay = new Date(year,month-1,1).getDay();
		var selectDate = options.selectDate;
		selectDate = typeof selectDate == 'string' ? selectDate.indexOf('-') != -1 ? selectDate.split('-')  : null : null;
		if( selectDate ){
			selectDate[0] = selectDate[0] == 'each' ? year : parseInt(selectDate[0]);
			selectDate[1] = selectDate[1] == 'each' ? month : parseInt(selectDate[1]);
			selectDate[2] = selectDate[2] == 'each' ? 1 : parseInt(selectDate[2]);
		}
		for(var j = 0; j < 42; j++){
			if( j % 7 == 0 && j != 41 ){
				if( j != 0){
					calendar +="</tr><tr>";
				}
				else{
					calendar +="<tr>";
				}
			}
			//当前月
			if( j >= firDay && ( j < (firDay + monthLen)) ){
				if( options.today ){
					if( j == parseInt(options.crtdate) + firDay - 1 && options.realyear == year && parseInt(options.realmonth) == month){
						if( selectDate && selectDate[0] == year && selectDate[1] == month && selectDate[2] == parseInt(options.crtdate) ){
							calendar += '<td class="current-month current-day selected-day tdday day'+(j % 7)+'" data-time="'+year+'-'+this.dispose(month)+'-'+this.dispose((j - firDay + 1))+'"><span class="day">'+(j-firDay+1)+'</span></td>';								
						}else{
							calendar += '<td class="current-month current-day tdday day'+(j % 7)+'" data-time="'+year+'-'+this.dispose(month)+'-'+this.dispose((j - firDay + 1))+'"><span class="day">'+(j-firDay+1)+'</span></td>';
						}
					}else{
						if( selectDate && selectDate[0] == year && selectDate[1] == month && selectDate[2] == ( j -firDay + 1 )){
							calendar +='<td class="current-month selected-day tdday day'+(j % 7)+'" data-time="'+year+'-'+this.dispose(month)+'-'+this.dispose((j - firDay + 1))+'"><span class="day">'+(j-firDay+1)+'</span></td>';
						}else{
							calendar +='<td class="current-month tdday day'+(j % 7)+'" data-time="'+year+'-'+this.dispose(month)+'-'+this.dispose((j - firDay + 1))+'"><span class="day">'+(j-firDay+1)+'</span></td>';
						}
					}
				}else{
					if( selectDate && selectDate[0] == year && selectDate[1] == month && selectDate[2] == ( j -firDay + 1 )){
						calendar +='<td class="current-month selected-day tdday day'+(j % 7)+'" data-time="'+year+'-'+this.dispose(month)+'-'+this.dispose((j - firDay + 1))+'"><span class="day">'+(j-firDay+1)+'</span></td>';
					}else{
						calendar +='<td class="current-month tdday day'+(j % 7)+'" data-time="'+year+'-'+this.dispose(month)+'-'+this.dispose((j - firDay + 1))+'"><span class="day">'+(j-firDay+1)+'</span></td>';
					}
				}
			}	
			//上个月
			else if( j < firDay ){
				if( selectDate && ( selectDate[0] + '-' + selectDate[1] ) == prevdate && selectDate[2] == (prevMonthLen - (firDay - j - 1)) ){
					calendar +='<td class="other-month selected-day prev-month day'+(j % 7)+'" data-time="'+prevdate+'-'+this.dispose((prevMonthLen - (firDay - j - 1)))+'"><span class="day">'+(prevMonthLen - (firDay - j - 1))+'</span></td>';						
				}else{
					calendar +='<td class="other-month prev-month day'+(j % 7)+'" data-time="'+prevdate+'-'+this.dispose((prevMonthLen - (firDay - j - 1)))+'"><span class="day">'+(prevMonthLen - (firDay - j - 1))+'</span></td>';	
				}
			}
			//下个月
			else if( j >= (firDay + monthLen)){
				if( selectDate && ( selectDate[0] + '-' + selectDate[1] ) == nextdate && selectDate[2] == (j - monthLen - firDay + 1) ){
					calendar += '<td class="other-month selected-day next-month day'+(j % 7)+'" data-time="'+nextdate+'-'+this.dispose((j - monthLen - firDay + 1))+'"><span class="day">'+(j - monthLen - firDay + 1)+'</span></td>';					
				}else{
					calendar += '<td class="other-month next-month day'+(j % 7)+'" data-time="'+nextdate+'-'+this.dispose((j - monthLen - firDay + 1))+'"><span class="day">'+(j - monthLen - firDay + 1)+'</span></td>';					
				}
			}
			

		}
		calendar +='</tr>';
		return calendar;
	}

	Calendar.prototype.bulidWeekly = function(options, year ,month){
		var calendar = '';
		var numbers = options.numbers;
		var month  = month ? parseInt(month) : parseInt(options.setMonth);
		var year = year ? parseInt(year) : parseInt(options.setYear);
		var prevdate = this.getPrev(year, month, 'weekly');
		var nextdate = this.getNext(year, month, 'weekly');
		var monthLen = eli.getMonthLen(year, month);
		var prevMonth = prevdate.split('-')[1];
		var nextMonth = nextdate.split('-')[1];
		var prevMonthLen = eli.getMonthLen(prevdate.split('-')[0], prevMonth);
		var firDay = new Date(year,month-1,1).getDay();
		firDay = firDay == 0 ? 7 : firDay;
		var startDay  = firDay != 1 ? prevMonthLen - firDay + 2 : 1 ;
		var startMonth  = startDay != 1? prevMonth : month ;
		var endDay  = parseInt(startDay) + 6 > parseInt(prevMonthLen)? parseInt(startDay) + 6 - parseInt(prevMonthLen) : parseInt(startDay) + 6;
		var startYear  = startMonth > month ? year - 1 : year ;
		var endYear  = startMonth == 12 ? startYear + 1 : startYear ;
		var selectDate = options.selectDate;
		selectDate = typeof selectDate == 'string' ? selectDate.indexOf('-') != -1 ? selectDate.split('-')  : null : null;
		if( selectDate ){
			selectDate[0] = selectDate[0] == 'each' ? year : parseInt(selectDate[0]);
			selectDate[1] = selectDate[1] == 'each' ? month : parseInt(selectDate[1]);
			selectDate[2] = selectDate[2] == 'each' ? 'week1' : selectDate[2].indexOf('week') != -1 ? selectDate[2] : parseInt(selectDate[2]);
			if( typeof selectDate[2] == 'number'){ selectDate[2] = eli.getMonthWeek(selectDate[0], selectDate[1], selectDate[2])}
		}
		var crt;
		for(var j = 0; j < 5; j++ ){
			if( j != 0 && parseInt(startDay) >= parseInt(endDay) ){
				if( selectDate ){
					crt = 'week' + ( j + 1 );
					if( ($.isArray(selectDate[2]) && (year == selectDate[2][0][0] && month == selectDate[2][0][1] && selectDate[2][0][2] == crt)) || ( year == selectDate[0] && month == selectDate[1] && selectDate[2] == crt ) ){
						calendar += '<tr><td class="selected-week tweek week'+(j + 1)+'" data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(month)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(nextMonth)+'/'+this.dispose(endDay)+'</span></div></td></tr>';					
					}
					else{
					    calendar += '<tr><td class="tweek week'+(j + 1)+'" data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(nextMonth)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(nextMonth)+'/'+this.dispose(endDay)+'</span></div></td></tr>';											
					}
				}else{
					calendar += '<tr><td class="tweek week'+(j + 1)+'" data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(nextMonth)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(nextMonth)+'/'+this.dispose(endDay)+'</span></div></td></tr>';					
				}
			}
			else if( options.today && ( (parseInt(options.realmonth) == startMonth && startDay <= parseInt(options.crtdate)) || ( parseInt(options.realmonth) != startMonth && startDay >= parseInt(options.crtdate)) ) && parseInt(options.crtdate) <= endDay && options.realyear == year && options.realmonth == month){
				if( selectDate ){
					crt = 'week' + ( j + 1 );
					if( ($.isArray(selectDate[2]) && ((year == selectDate[2][0][0] && month == selectDate[2][0][1] && selectDate[2][0][2] == crt) || ( selectDate[2][1] && year == selectDate[2][1][0] && month == selectDate[2][1][1] && selectDate[2][1][2] == crt))) ||  ( year == selectDate[0] && month == selectDate[1] && selectDate[2] == crt )  ){
						calendar += '<tr><td class="current-week current-day selected-week tweek week'+(j + 1)+'" data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(month)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(month)+'/'+this.dispose(endDay)+'</span></div></td></tr>';						
					}else{
						calendar += '<tr><td class="current-week current-day tweek week'+(j + 1)+'" data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(month)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(month)+'/'+this.dispose(endDay)+'</span></div></td></tr>';
					}
				}else{
					calendar += '<tr><td class="current-week current-day tweek week'+(j + 1)+'" data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(month)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(month)+'/'+this.dispose(endDay)+'</span></div></td></tr>';
				}
			}
			else if( selectDate ){
				crt = 'week' + ( j + 1 );
				if( ($.isArray(selectDate[2]) && ((year == selectDate[2][0][0] && month == selectDate[2][0][1] && selectDate[2][0][2] == crt) || ( selectDate[2][1] && year == selectDate[2][1][0] && month == selectDate[2][1][1] && selectDate[2][1][2] == crt))) ||  ( year == selectDate[0] && month == selectDate[1] && selectDate[2] == crt )  ){
					calendar += '<tr><td class="selected-week tweek week'+(j + 1)+'" data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(month)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(month)+'/'+this.dispose(endDay)+'</span></div></td></tr>';					
				}else{
					calendar += '<tr><td class="tweek week'+(j + 1)+'"  data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(month)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(month)+'/'+this.dispose(endDay)+'</span></div></td></tr>';
				}
			}
			else{
				calendar += '<tr><td class="tweek week'+(j + 1)+'"  data-time="'+startYear+'-'+this.dispose(startMonth)+'-'+this.dispose(startDay)+','+endYear+'-'+this.dispose(month)+'-'+this.dispose(endDay)+'" colspan="7"><div><span class="week">第'+ numbers[j] +'周</span><span class="process">'+this.dispose(startMonth)+'/'+this.dispose(startDay)+'~'+this.dispose(month)+'/'+this.dispose(endDay)+'</span></div></td></tr>';
			}

			if( j == 0 && firDay != 1){
				startMonth = parseInt(startMonth) + 1 > 12 ? '1' : parseInt(startMonth) + 1 ; 
				startDay = parseInt(endDay) + 1;
			}else{
				startDay += 7;
			}
			
			endDay = startDay + 6 > monthLen ? startDay + 6 - monthLen : startDay + 6;
			startYear = startMonth > month ? year - 1 : year ;
			endYear = startMonth == 12 ? startYear + 1 : startYear ;
			
		}
		return calendar;

	}

	Calendar.prototype.forWeek = function (year ,month){
		var endMonth = parseInt(month) ;
		var year = parseInt(year) ;
		var prevdate = this.getPrev(year, month, 'weekly');
		var monthLen = eli.getMonthLen(year, month);
		var prevMonth = prevdate.split('-')[1];
		var prevMonthLen = eli.getMonthLen(prevdate.split('-')[0], prevMonth);
		var firDay = new Date(year, month - 1, 1).getDay();
		firDay = firDay == 0 ? 7 : firDay;
		var startDay = firDay != 1 ? prevMonthLen - firDay + 2 : 1 ;
		var startMonth = startDay != 1? prevMonth : month ;
		var endDay = parseInt(startDay) + 6 > parseInt(prevMonthLen)? parseInt(startDay) + 6 - parseInt(prevMonthLen) : parseInt(startDay) + 6;
		var startYear = parseInt(startMonth) > month ? year - 1 : year ;
		var endYear = startMonth == 12 ? startYear + 1 : startYear ;
		var data = startYear +'-'+ this.dispose(startMonth) + '-' +this.dispose(startDay) +',' + endYear +'-' + this.dispose(month) + '-'+ this.dispose(endDay);
		return data;
	}

	Calendar.prototype.bulidMonthly = function(options, year ,month){
		var calendar = '';
		var month = month ? parseInt(month) : parseInt(options.setMonth);
		var year = year ? parseInt(year) : parseInt(options.setYear);
		var selectDate = options.selectDate;
		selectDate = typeof selectDate == 'string' ? selectDate.indexOf('-') != -1 && selectDate.indexOf('week') == -1 ?  selectDate.split('-') : null : null;
		if(selectDate){
			selectDate[0] = selectDate[0] == 'each' ? year : parseInt(selectDate[0]);
			selectDate[1] = selectDate[1] == 'each' ? 1 : parseInt(selectDate[1]);
		}
		for(var j = 0; j < 12; j++){
			if( j % 4 == 0 && j !=12 ){
				if( j != 0){
					calendar +="</tr><tr>";
				}
				else{
					calendar +="<tr>";
				}
			}
			if( options.today && (j + 1) == options.realmonth && options.realyear == year){
				if( selectDate && selectDate[0] == year && selectDate[1] == (j + 1)){
					calendar += '<td colspan=2 class="current-month current-day selected-month selected-day tmonth month'+this.dispose(( j + 1 ))+'" data-time="'+year+'-'+this.dispose(( j + 1 ))+'"><span class="month">'+(j + 1)+'月</span></td>';
				}else{
					calendar += '<td colspan=2 class="current-month current-day tmonth month'+this.dispose(( j + 1 ))+'" data-time="'+year+'-'+this.dispose(( j + 1 ))+'"><span class="month">'+(j + 1)+'月</span></td>';
				}
			}else if( selectDate && selectDate[0] == year && selectDate[1] == (j + 1)){
				calendar += '<td colspan=2 class="selected-month selected-day tmonth month'+this.dispose(( j + 1 ))+'" data-time="'+year+'-'+this.dispose(( j + 1 ))+'"><span class="month">'+(j + 1)+'月</span></td>'
			}else{
				calendar += '<td colspan=2 class="tmonth month'+this.dispose(( j + 1 ))+'" data-time="'+year+'-'+this.dispose(( j + 1 ))+'"><span class="month">'+(j + 1)+'月</span></td>'
			}
		}
		calendar +='</tr>';
		return calendar;

	}

	Calendar.prototype.getNext = function(year, month, type){
		var nextdate;
		if(type == 'monthly'){
			nextdate = parseInt(year) + 1 + '-';
		}else{
			nextdate = parseInt(month) == 12 ? parseInt(year) + 1 + '-01' : year + '-' + this.dispose((parseInt(month) + 1));
		}
		return nextdate;
	}

	Calendar.prototype.getPrev = function(year, month, type){
		var prevdate;
		if(type == 'monthly'){
			prevdate = parseInt(year) - 1 + '-';
		}else{
			prevdate = parseInt(month) == 1 ? parseInt(year) - 1 + '-12' : year + '-' + this.dispose((parseInt(month) - 1));
		}
		return prevdate;
	}

	Calendar.prototype.getDate = function(){
		var now = new Date();
		var crtdate = now.getDate();
		var setMonth = now.getMonth() + 1 ;
		var setYear = now.getYear() + 1900;
		crtdate = this.dispose(crtdate);
		setMonth = this.dispose(setMonth);
		var date = {
			crtdate : crtdate,
			realmonth : setMonth,
			setMonth : setMonth,
			realyear : setYear,
			setYear : setYear
		}
		return date;
	}

	Calendar.prototype.dispose = function(val){
		var value = (parseInt(val)+100);
		value=value.toString();
		value=value.substring(1);
		return value;
	}

	Calendar.prototype.getOptions = function(options, date){
		if(options && typeof options == 'object'){
			$.each(options , function(key, value){
				if(value == void 0){
					delete options[key];
				}
			})
		}
		var option = $.extend({target : null }, CALENDAR_OPTION, date, options);
		return option;
	}

	var Plugin = function( option ){
		return this.each(function(){
			var $this = $(this);
			var data = $this.data( 'ellie.calendar' );
			var options = typeof option == 'object' && option;
			if( !data ) $this.data( 'ellie.calendar', ( data = new Calendar(this, option) ) )
		})
	}

	$.fn.flexoCalendar = Plugin;
	$.fn.flexoCalendar.Constructor = Calendar;

	var old = $.fn.flexoCalendar;

  // calendarWidget no conflict

	$.fn.flexoCalendar.noConflict = function () {
	  	$.fn.flexoCalendar = old;
    	return this;
	}

})(jQuery)

+(function($){
	var root=this;
	var eli = function(obj) {
    	if (obj instanceof eli) return obj;
    	if (!(this instanceof eli)) return new eli(obj);
    	this.eliwrapped = obj;
  	};

  	root.eli = eli;

	eli.getMonthLen = function(year, month){
		var year = parseInt(year);
		var month = parseInt(month);
		var monthLen=[,31,28,31,30,31,30,31,31,30,31,30,31];
		if ((month == 2)&&(year % 4 == 0)&&((year % 100 != 0)||(year % 400 == 0))){
		  return 29;
		}else{
		  return monthLen[month];
		}
	}

	eli.getMonthWeek = function(year, month, day){
		var year = parseInt(year),
			month = parseInt(month),
			day = parseInt(day);
		var that = [year, month,],
			firDay = new Date(year, month - 1, 1).getDay(),
			start = 1,
			next = 8,
			monthLen = eli.getMonthLen(year, month),
		    nextfirDay = new Date(year , month, 1 ).getDay(),
		    another; 
		firDay = firDay == 0 ? 7 : firDay;
		next = firDay == 1 ? next : ( 9 - firDay );
		
		for ( var i = 0; i < 5 ; i++){
			if( start <= day && day < next){
				that[2] = 'week' + ( i + 1 );
			}
			start = next ;
			next += 7;
			next = next > monthLen ? monthLen : next;
		}
		if( nextfirDay !=1 ){
			another = [,,'week1'];
			another[1] = month + 1 == 13 ? 1 : month + 1;
			another[0] = another[1] == 1 ? year + 1 : year;
		}
		var output = [that, another];
		return output
	}
})(jQuery)

以上为封装的插件主要js文件,将上述代码保存至js文件里引用即可

@charset "utf-8";
blockquote,body,button,caption,dd,div,dl,dt,fieldset,figure,form,h1,h2,h3,h4,h5,h6,html,input,legend,li,menu,ol,p,pre,.flexoCalendar,td,textarea,th,ul{margin:0;padding:0}
*{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;font-family:'微软雅黑',"Microsoft YaHei",'宋体',Arial,Microsoft YaHei,Helvetica,sans-serif;}
.calendar-wrapper{position: relative;margin-bottom: 20px;width: 230px;margin:15px auto;background: #fff;min-height:155px;}
.calendar-wrapper .flexoCalendar{margin:0 auto;border-collapse:separate;width: 100%;position: relative;z-index: 1}
.flexoCalendar td,.flexoCalendar th{border:0 none;height:27px;text-align:center;width:32px;font-size:12px;cursor:pointer}
.flexoCalendar tr th .icon-arrow-left{display:inline-block;height:16px;line-height:16px;margin-top:4px;vertical-align:text-top;width:12px;cursor:pointer}
.flexoCalendar tr th .icon-arrow-right{display:inline-block;height:16px;line-height:16px;margin-top:4px;vertical-align:text-top;width:12px;cursor:pointer}
.icon-arrow-left:before{content: '<';font-style: normal;}
.icon-arrow-right:before{content: '>';font-style: normal;}
.flexoCalendar thead tr{height:25px;color: #fff;}
.flexoCalendar thead tr:first-child th{cursor:pointer}
.flexoCalendar thead tr:first-child th:hover{background:#3dbaf0}
.flexoCalendar tr td.other-month{color:#aaa}
.flexoCalendar thead,.flexoCalendar th{background-color: #3dbaf0;font-weight: normal;color: #fff;}
.flexoCalendar tr th.current-year{width: 60%;}
.flexoCalendar td.selected-day span{color:  #3dbaf0;} 
.flexoCalendar tr td .day{display: block;width: 30px;height: 25px;line-height: 22px;text-align: center;margin:1px;border:1px solid transparent;}
.flexoCalendar tr td.current-day>div,.flexoCalendar td.current-day>span{border:1px solid #3dbaf0!important;border-radius: 4px;color:#3dbaf0;background: #fff;}
.flexoCalendar tr td.selected>div,.flexoCalendar tr td.selected>span,.flexoCalendar tr td.selected>div span{border:1px solid #3dbaf0;border-radius: 4px;background-color:#3dbaf0;color: #fff!important}
#calendar-weekly .calendar-hd,#calendar-monthly .calendar-hd,#calendar-weekly tbody td{height: 30px;}
#calendar-weekly tr td div{margin-bottom: 2px;}
#calendar-weekly tr td .week{width: 100%;height: 100%;line-height: 30px;color:#565656;text-align: center;}
#calendar-weekly tr td .process{color:#999;margin-left: 20px;display: inline-block;width: 57px;text-align: left;}
#calendar-monthly td.tmonth .month{display: block;width: 55px;height: 30px;line-height:30px;margin:1px;text-align: center;border-radius: 4px;color: #565656;border:1px solid transparent;}
#calendar-monthly td.current-month .month{border:1px solid #3dbaf0;}
#calendar-weekly tr td.week1 div,.tmonth.month1 span,.tmonth.month2 span,.tmonth.month3 span,.tmonth.month4 span{margin-top: 10px!important;}

以上为插件样式,使用条件与上面js一般如此

<!DOCTYPE html>
<!-- saved from url=(0082)http://www.17sucai.com/preview/320784/2018-05-04/FlexoCalendar.js-master/demo.html -->
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	
	<title>FlexoCalendar</title>
	
	<link rel="stylesheet" href="./FlexoCalendar_files/FlexoCalendar.css">
	
	<script type="text/javascript" src="./FlexoCalendar_files/jquery.js.下载"></script>
	<script type="text/javascript" src="./FlexoCalendar_files/FlexoCalendar.js.下载"></script>
	
</head>
<body style="background:#f5f5f5;">

	<div class="calendar-wrapper">
		<div id="calendar"><table class="flexoCalendar " id="" cellspacing="0"><thead><tr class="calendar-hd"><th class="prev" data-month="2015-03"><i class="icon-arrow-left"></i></th><th class="current-year" data-year="2015-04" colspan="5">2015年04月</th><th class="next" data-month="2015-05"><i class="icon-arrow-right"></i></th></tr><tr class="weekday"><th data-day="day0">日</th><th data-day="day1">一</th><th data-day="day2">二</th><th data-day="day3">三</th><th data-day="day4">四</th><th data-day="day5">五</th><th data-day="day6">六</th></tr></thead><tbody><tr><td class="other-month prev-month day0" data-time="2015-03-29"><span class="day">29</span></td><td class="other-month prev-month day1" data-time="2015-03-30"><span class="day">30</span></td><td class="other-month prev-month day2" data-time="2015-03-31"><span class="day">31</span></td><td class="current-month selected-day tdday day3" data-time="2015-04-01"><span class="day">1</span></td><td class="current-month tdday day4" data-time="2015-04-02"><span class="day">2</span></td><td class="current-month tdday day5" data-time="2015-04-03"><span class="day">3</span></td><td class="current-month tdday day6" data-time="2015-04-04"><span class="day">4</span></td></tr><tr><td class="current-month tdday day0" data-time="2015-04-05"><span class="day">5</span></td><td class="current-month tdday day1" data-time="2015-04-06"><span class="day">6</span></td><td class="current-month tdday day2" data-time="2015-04-07"><span class="day">7</span></td><td class="current-month tdday day3" data-time="2015-04-08"><span class="day">8</span></td><td class="current-month tdday day4" data-time="2015-04-09"><span class="day">9</span></td><td class="current-month tdday day5" data-time="2015-04-10"><span class="day">10</span></td><td class="current-month tdday day6" data-time="2015-04-11"><span class="day">11</span></td></tr><tr><td class="current-month tdday day0" data-time="2015-04-12"><span class="day">12</span></td><td class="current-month tdday day1" data-time="2015-04-13"><span class="day">13</span></td><td class="current-month tdday day2" data-time="2015-04-14"><span class="day">14</span></td><td class="current-month tdday day3" data-time="2015-04-15"><span class="day">15</span></td><td class="current-month tdday day4" data-time="2015-04-16"><span class="day">16</span></td><td class="current-month tdday day5" data-time="2015-04-17"><span class="day">17</span></td><td class="current-month tdday day6" data-time="2015-04-18"><span class="day">18</span></td></tr><tr><td class="current-month tdday day0" data-time="2015-04-19"><span class="day">19</span></td><td class="current-month tdday day1" data-time="2015-04-20"><span class="day">20</span></td><td class="current-month tdday day2" data-time="2015-04-21"><span class="day">21</span></td><td class="current-month tdday day3" data-time="2015-04-22"><span class="day">22</span></td><td class="current-month tdday day4" data-time="2015-04-23"><span class="day">23</span></td><td class="current-month tdday day5" data-time="2015-04-24"><span class="day">24</span></td><td class="current-month tdday day6" data-time="2015-04-25"><span class="day">25</span></td></tr><tr><td class="current-month tdday day0" data-time="2015-04-26"><span class="day">26</span></td><td class="current-month tdday day1" data-time="2015-04-27"><span class="day">27</span></td><td class="current-month tdday day2" data-time="2015-04-28"><span class="day">28</span></td><td class="current-month tdday day3" data-time="2015-04-29"><span class="day">29</span></td><td class="current-month tdday day4" data-time="2015-04-30"><span class="day">30</span></td><td class="other-month next-month day5" data-time="2015-05-01"><span class="day">1</span></td><td class="other-month next-month day6" data-time="2015-05-02"><span class="day">2</span></td></tr><tr><td class="other-month next-month day0" data-time="2015-05-03"><span class="day">3</span></td><td class="other-month next-month day1" data-time="2015-05-04"><span class="day">4</span></td><td class="other-month next-month day2" data-time="2015-05-05"><span class="day">5</span></td><td class="other-month next-month day3" data-time="2015-05-06"><span class="day">6</span></td><td class="other-month next-month day4" data-time="2015-05-07"><span class="day">7</span></td><td class="other-month next-month day5" data-time="2015-05-08"><span class="day">8</span></td><td class="other-month next-month day6" data-time="2015-05-09"><span class="day">9</span></td></tr></tbody></table></div>
	</div>
	<div class="calendar-wrapper">
		<div id="calendar-weekly"><table class="flexoCalendar " id="" cellspacing="0"><thead><tr class="calendar-hd"><th class="prev" data-month="2019-03" data-week="2019-02-25,2019-03-03"><i class="icon-arrow-left"></i></th><th class="current-year" data-year="2019-04" colspan="5">2019年04月</th><th class="next" data-month="2019-05" data-week="2019-04-29,2019-05-05"><i class="icon-arrow-right"></i></th></tr></thead><tbody><tr><td class="tweek week1" data-time="2019-04-01,2019-04-07" colspan="7"><div><span class="week">第一周</span><span class="process">04/01~04/07</span></div></td></tr><tr><td class="tweek week2" data-time="2019-04-08,2019-04-14" colspan="7"><div><span class="week">第二周</span><span class="process">04/08~04/14</span></div></td></tr><tr><td class="tweek week3" data-time="2019-04-15,2019-04-21" colspan="7"><div><span class="week">第三周</span><span class="process">04/15~04/21</span></div></td></tr><tr><td class="tweek week4" data-time="2019-04-22,2019-04-28" colspan="7"><div><span class="week">第四周</span><span class="process">04/22~04/28</span></div></td></tr><tr><td class="tweek week5" data-time="2019-04-29,2019-05-05" colspan="7"><div><span class="week">第五周</span><span class="process">04/29~05/05</span></div></td></tr></tbody></table></div>
	</div>
	<div class="calendar-wrapper">
		<div id="calendar-monthly"><table class="flexoCalendar " id="" cellspacing="0"><thead><tr class="calendar-hd"><th class="prev" data-month="2018-" colspan="2"><i class="icon-arrow-left"></i></th><th class="current-year" data-year="2019-04" colspan="4">2019年</th><th class="next" data-month="2020-" colspan="2"><i class="icon-arrow-right"></i></th></tr></thead><tbody><tr><td colspan="2" class="tmonth month01" data-time="2019-01"><span class="month">1月</span></td><td colspan="2" class="tmonth month02" data-time="2019-02"><span class="month">2月</span></td><td colspan="2" class="tmonth month03" data-time="2019-03"><span class="month">3月</span></td><td colspan="2" class="current-month current-day tmonth month04" data-time="2019-04"><span class="month">4月</span></td></tr><tr><td colspan="2" class="tmonth month05" data-time="2019-05"><span class="month">5月</span></td><td colspan="2" class="tmonth month06" data-time="2019-06"><span class="month">6月</span></td><td colspan="2" class="tmonth month07" data-time="2019-07"><span class="month">7月</span></td><td colspan="2" class="tmonth month08" data-time="2019-08"><span class="month">8月</span></td></tr><tr><td colspan="2" class="tmonth month09" data-time="2019-09"><span class="month">9月</span></td><td colspan="2" class="tmonth month10" data-time="2019-10"><span class="month">10月</span></td><td colspan="2" class="tmonth month11" data-time="2019-11"><span class="month">11月</span></td><td colspan="2" class="tmonth month12" data-time="2019-12"><span class="month">12月</span></td></tr></tbody></table></div>
	</div>
	
	
	<script type="text/javascript">
		$("#calendar").flexoCalendar({setYear:2015,setMonth:4, selectDate: 'each-each-each'});
		$("#calendar-weekly").flexoCalendar({type:'weekly',today:false});
		$("#calendar-monthly").flexoCalendar({
			type: 'monthly',
			onselect: function(date){
				console.log(date)
			}
		});
	</script>
	


</body></html>

以上为实例代码,仅供参考

之前在网上想找一个简单易用的选择插件,发现这种前端插件很少,而且很多文章写的的算法都不是统一的,所以自己实现了一个基于jquery的插件(还支持跳转到指定年份和)插件的算法:每为起始,第一以每年第一个星期四所在的为第一(网上找的好像这个算法比较正规) 实现的效果是在手机端,也可以在PC端用,毕竟功能才是主要的。如果觉得样式不入眼可以自行随意修改。 //调用历方法 var weekfn = new jcalendar_week({ element: "#jcalendar_week",//填充历的dom元素 dayaddclass:function(date){ //添加某天时给添加类名(参数:1.)(返回类名字符串,多个以空格分开) return ""; }, dayclick:function(date,obj){ //day点击事件(参数:1.期,2.所点击DOM元素) $(obj).addClass("calendar_day_act").siblings().removeClass("calendar_day_act"); } }); 点击上方显示当前年份和的DOM部分可选择并跳转到指定年份和插件提供的方法: //获取第一天方法weekfirstdate(),传入年份和数 console.log(weekfn.weekfirstdate(2018,36)); //获取传入期为当年第几getweeknum(),传入年,,(注:这里的份从0开始) console.log(weekfn.getweeknum(2018,0,16)); //跳转到指定confirmweek(),传入年份和数 weekfn.confirmweek(getyear,getweek); //跳转到本nowweek() weekfn.nowweek();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值