js移动端日历,可标记点,选范围

说明:依赖jquery,设置选择范围,设置标记点,文字和点等,可自定义格式化文字。

各方法所需参数请查看源码说明

效果:

 

 

 

源码:

/**
 * Name:calender.js
 * Author:Li
 * E-mail:1562321291@qq.com
 * Time: 2019-8-22 10:07:56
 * time:时间
 * text:文本
 * markPoint:true/false,是否显示点
 * pointText:右上角是否显示为文字
 * formatText:function,格式化底部文本
 */
var calendarWidget = {
	config: {},
	htmlStr: "",
	topSelecter: undefined,
	year: undefined,
	month: undefined,
	day: undefined,
	range:{  //标记范围
		start:undefined,
		end:undefined
	},
	/**
	 * 初始化
	 * @param {obj} data 以下为data的参数
	 * @param {string} currentTime  当前时间 yyyy-MM-dd
	 * @param {string} elem			绑定div的id  带#
	 * @param {array} mark			标记点列表
	 * @param {function} change		日期改变事件回调
	 * @param {function} mounted		渲染完成事件回调
	 * @param {function} dateclick	顶头的日期点击回调,可以通过此回调选择月份
	 * @param {function} formatText	格式化底部的文字
	 * @param {string} lastText		上月文字
	 * @param {string} nextText		下月文字
	 * */
	initCalculate: function(data) {  
		calendarWidget.config = data || {
			currentTime: "",  		//当前时间 yyyy-MM-dd
			elem: undefined,  		//绑定div的id  带#
			mark: [],         		//标记点列表
			change: undefined,      //日期改变事件回调
			mounted:undefined,      //渲染完成事件回调
			dateclick:undefined,	//顶头的日期点击回调,可以通过此回调选择月份
			formatText:undefined, 	//格式化底部的文字
			startDate:undefined,  	//选择的开始时间,此时间之前为灰色状态 yyyy-MM-dd		未实现
			endDate:undefined,    	//选择的结束时间,此时间之后为灰色状态 yyyy-MM-dd		未实现
			lastText:'〈',			//上月文字
			nextText:'〉',			//下月文字
		};
		calendarWidget.config.lastText = data.lastText?data.lastText:'〈';
		calendarWidget.config.nextText = data.nextText?data.nextText:'〉'
		
		if (!calendarWidget.config.elem) {
			console.error("element is not set");
			return;
		}
		if (calendarWidget.config.currentTime == "" || calendarWidget.config.currentTime == undefined) {
			calendarWidget.config.currentTime = new Date().getFullYear() + "/" + (new Date().getMonth() + 1) + "/01";
		}
		calendarWidget.config.currentTime = calendarWidget.config.currentTime.replace(/-/g, "/");
		
		//设置开始时间
		if(calendarWidget.config.startDate){
			calendarWidget.config.startDate = new Date(calendarWidget.config.startDate.replace(/-/g, "/")); 
			if(calendarWidget.config.startDate == "Invalid Date"){
				console.error('startDate config error');
				calendarWidget.config.startDate = undefined;
			}
		}
		
		//设置结束时间
		if(calendarWidget.config.endDate){
			calendarWidget.config.endDate = new Date(calendarWidget.config.endDate.replace(/-/g, "/")); 
			if(calendarWidget.config.endDate == "Invalid Date"){
				console.error('endDate config error');
				calendarWidget.config.endDate = undefined;
			}
		}
		
		calendarWidget.renderCalendar();
	},
	renderCalendar: function() {  //生成日历
		calendarWidget.day = "";
		calendarWidget.config.currentTime = calendarWidget.config.currentTime.replace(/-/g, "/");
		var tempDateWidget = new Date(calendarWidget.config.currentTime);
		calendarWidget.config.currentTime = tempDateWidget.getFullYear() + "/" + (tempDateWidget.getMonth() + 1) + "/01"; //重置当前时间月份1号
		
		var totalDay = calendarWidget.getTotalDay(calendarWidget.config.currentTime); //获取一个月的天数
		var date = new Date(calendarWidget.config.currentTime);
		 
		calendarWidget.year = date.getFullYear();
		calendarWidget.month = date.getMonth() + 1;
		var firstDayWeek = date.getDay(); //第一天是星期几
		var textStr = calendarWidget.year + "年" + calendarWidget.month + '月';  //顶部显示的日期
		var sum = 0;
		var htmlStr = "";
		//获取上一个月的天数
		var TempMonth;
		var TempYear;
		if (calendarWidget.month == 1) { //跨年
			TempMonth = 12;
			TempYear = calendarWidget.year - 1;
		} else {
			TempYear = calendarWidget.year;
			TempMonth = calendarWidget.month - 1;
		}
		var TempLastMonthStr = TempYear + "/" + TempMonth + "/01";
		var lastMonthTotalDay = calendarWidget.getTotalDay(TempLastMonthStr);
		var lastMonthStartDay = lastMonthTotalDay - firstDayWeek;
		// 创建前面的日期
		for (var i = 0; i < firstDayWeek; i++) {
			sum++;
			lastMonthStartDay++;
			htmlStr += '<div class="calendar-col aligncanter calendar-col-lastMonth">' + lastMonthStartDay + '</div>';
		}
		var dayStr = calendarWidget.year + "-" + calendarWidget.month;
		//获取当前时间
		var currentDateTemp = new Date().getFullYear() + "-" + (new Date().getMonth() + 1) + "-" + new Date().getDate();

		//生成日历
		for (var i = 1; i <= totalDay; i++) { //循环日
			sum++;

			var tempDay = dayStr + "-" + i; //日期字符串
			var fontText = i;  //日期数字
			//当前日期变量
			var tempCurrTime = new Date(tempDay.replace('-','/').replace('-','/'));
			
			var tempCurrWeek = tempCurrTime.getDay();
			if(tempCurrWeek == 0 || tempCurrWeek == 6) //周六和周日,特殊处理
				fontText = "<span class='calendar-day-6-7'>" + fontText +"</span>";
			var textTemp = "<div class='dayValue'>" + fontText + "<span class='calendar-point'></span><span class='calendar-text'></span></div>";
			for (var z = 0; z < calendarWidget.config.mark.length; z++) { //判断是否为标记点
				if (tempDay == calendarWidget.config.mark[z].time.trim()) {
					var tempTextStr = calendarWidget.config.formatText == undefined? calendarWidget.config.mark[z].text 
										: calendarWidget.config.formatText(calendarWidget.config.mark[z].text);
					textTemp = "<div class='dayValue'>" + fontText;
					if (calendarWidget.config.mark[z].markPoint != false) // 是否显示点
						textTemp += calendarWidget.config.mark[z].pointText? '<span class="calendar-point">'+calendarWidget.config.mark[z].pointText+'</span>' : '<span class="calendar-point">●</span>';
					if (tempTextStr != undefined && tempTextStr != "") // 是否显示文字
						textTemp += '<div class="calendar-text">' + tempTextStr + '</div>';
					textTemp += "</div>";
					break;
				}
			}
			
			
			//如果设置了范围
			var calendar_range = "";
			if(calendarWidget.range.start && calendarWidget.range.end){
				if(calendarWidget.range.start <= tempCurrTime && tempCurrTime <= calendarWidget.range.end)
					calendar_range = ' calendar-range ';
			}
			
			if (tempDay == currentDateTemp) {  //当天
				htmlStr += '<div class="calendar-col aligncanter currentDays calendar-today ' +calendar_range + '" data-day="' + i + '" data-date="' + tempDay + '">' + textTemp +
					'</div>';
			} else {  //其他
				htmlStr += '<div class="calendar-col aligncanter currentDays ' +calendar_range + '" data-day="' + i + '" data-date="' + tempDay + '">' + textTemp + '</div>';
			}
		}
		if (sum < 42) { // 创建后面的空白,补够五行
			var j = 0;
			for (var i = sum; i < 42; i++) {
				sum++;
				j++;
				htmlStr += '<div class="calendar-col aligncanter calendar-col-nextMonth">' + j + '</div>';
			}
		}
		
		var content = "<div class='calendar-Time-header under_line'><a class='calendar-lastMonth'>" +calendarWidget.config.lastText+ "</a><a  class='calendar-TimeH'>" +
			textStr + "<a><a class='calendar-nextMonth'>" +calendarWidget.config.nextText+ "</a> <a class='calendar-backToToday'>回到今天</a></div><div class='ClearBoth'></div>" +
			'<div class="calendar-content">' +
			'<div class="calendar-row calendar-header">' +
			'<div class="calendar-col aligncanter">日</div>' +
			'<div class="calendar-col aligncanter">一</div>' +
			'<div class="calendar-col aligncanter">二</div>' +
			'<div class="calendar-col aligncanter">三</div>' +
			'<div class="calendar-col aligncanter">四</div>' +
			'<div class="calendar-col aligncanter">五</div>' +
			'<div class="calendar-col aligncanter">六</div>' +
			'</div>' +
			'<div class="calendar-row calendar-day">' + htmlStr +
			'</div><div class="ClearBoth"></div> ' +
			'</div>';

		calendarWidget.htmlStr = content;
		$(calendarWidget.config.elem).html(calendarWidget.htmlStr);
		calendarWidget.bindEvent();
		if (calendarWidget.config.mounted) //初始化完成
			calendarWidget.config.mounted(calendarWidget.year + "/" + calendarWidget.month);
		return content;
	},
	bindEvent: function() { //绑定事件
		//点击顶部时间回调
		$(".calendar-TimeH").on('tap',function(){ 
			if(calendarWidget.config.dateclick){
				var textStr = calendarWidget.year + "-" + calendarWidget.month;
				calendarWidget.config.dateclick(calendarWidget, textStr);
			}
		})
		//每项点击
		$(".calendar-day").on('tap', '.currentDays', function() {  
			$(".calendar-active").removeClass("calendar-active");
			$(this).addClass("calendar-active");
			calendarWidget.day = $(this).attr("data-day");
			calendarWidget.change();
		})
		//日历中属于上个月的日期
		$(".calendar-day").on('tap', '.calendar-col-lastMonth', function() {
			var screenX = window.screen.width;
			calendarWidget.calendarTransform(screenX,300);
			setTimeout(function(){
				calendarWidget.subMonth();
			},300);
		})
		//日历中属于下个月的日期
		$(".calendar-day").on('tap', '.calendar-col-nextMonth', function() {
			var screenX = window.screen.width;
			screenX = -screenX;
			calendarWidget.calendarTransform(screenX,300);
			setTimeout(function(){
				calendarWidget.addMonth();
			},300);
		})
		
		//头部上月按钮
		$(".calendar-nextMonth").on('tap', function() {
			var screenX = window.screen.width;
			screenX = -screenX;
			calendarWidget.calendarTransform(screenX,300);
			setTimeout(function(){
				calendarWidget.addMonth();
			},300);
		})
		//头部下月按钮
		$(".calendar-lastMonth").on('tap', function() {
			var screenX = window.screen.width;
			calendarWidget.calendarTransform(screenX,300);
			setTimeout(function(){
				calendarWidget.subMonth();
			},300);
		})
		
		//头部回到今天按钮
		$(".calendar-backToToday").on('tap', function() {
			var currDate = new Date();
			var value = currDate.getFullYear() + "-" + (currDate.getMonth() + 1) + "-" + currDate.getDate();
			calendarWidget.setDate(value); 
		})
		
		
		//以下为实现日历左右滚动
		var startPageX = 0;
		var startPageY = 0;
		$(".calendar-day").on("touchstart", function(e) {
			startPageX = event.targetTouches[0].pageX;
			startPageY = event.targetTouches[0].pageY;
		})
		$(".calendar-day").on("touchmove", function(e) {
			var touchmovePageX = event.targetTouches[0].pageX;
			var result = touchmovePageX - startPageX;
			calendarWidget.calendarTransform(result,0);

		})
		$(".calendar-day").on("touchend", function(e) {
			var endPageX = event.changedTouches[0].pageX;
			var endPageY = event.changedTouches[0].pageY;
			var x = Math.abs(startPageX - endPageX); //横坐标之差
			var y = Math.abs(startPageY - endPageY); //纵坐标之差
			var screenX = window.screen.width;
			var screenY = window.screen.height;
			if (startPageX > endPageX) { //左滑
				var a = Math.atan(y / x);
				var Rate = x / screenX;
				if (a < Math.PI / 6 && Rate > 0.3) {
					screenX = -screenX;
					calendarWidget.calendarTransform(screenX,300);
					setTimeout(function(){
						calendarWidget.addMonth();
					},300);
				}
				else{
					calendarWidget.calendarTransform(0,300);
				}
			} else {
				var a = Math.atan(y / x);
				var Rate = x / screenX;
				if (a < Math.PI / 6 && Rate > 0.3) {
					calendarWidget.calendarTransform(screenX,300);
					setTimeout(function(){
						calendarWidget.subMonth();
					},300);
				}
				else{
					calendarWidget.calendarTransform(0,300);
				}
			}

		})
	},
	calendarTransform:function(x,time){  //日历滑动动画
		$(".calendar-day").css("transform", 'translate3d('+x+'px, 0px, 0px) translateZ(0px)'); 
		$(".calendar-day").css("transition-duration", time+"ms"); 
	},
	addMonth: function() { //加一个月
		if (calendarWidget.month == 12) { //跨年
			calendarWidget.month = 1;
			calendarWidget.year += 1;
		} else {
			calendarWidget.month += 1;
		}
		var str = calendarWidget.year + "/" + calendarWidget.month + "/01";
		calendarWidget.setDate(str);
	},
	subMonth: function() { //减一个月
		if (calendarWidget.month == 1) { //跨年
			calendarWidget.month = 12;
			calendarWidget.year -= 1;
		} else {
			calendarWidget.month -= 1;
		}
		var str = calendarWidget.year + "/" + calendarWidget.month + "/01";
		calendarWidget.setDate(str);
	},
	setDate:function(date){  //设置日期并重新生成日历
		calendarWidget.config.currentTime = date;
		calendarWidget.renderCalendar();
	},
	change: function() { //改变日期
		var tempd = calendarWidget.getSelectedDay();
		var markPoint = undefined;
		for (var z = 0; z < calendarWidget.config.mark.length; z++) { //判断是否为标记点
			if (tempd.indexOf(calendarWidget.config.mark[z].time) > -1) {
				markPoint = calendarWidget.config.mark[z];
			}
		}

		if (calendarWidget.config.change)
			calendarWidget.config.change(tempd, markPoint);
	},
	getSelectedDay: function() { //获取选择时间
		return calendarWidget.year + '-' + calendarWidget.month + '-' + calendarWidget.day;
	},
	/**
	 * 设置标记点,初始化完成后可执行
	 * @param {array} data 标记点列表
	 * [{
	 *   time:'yyyy-MM-dd',  string   标记时间  
	 * 	 text:'标记文本',	 string   标记文本  
	 *   markPoint:false,    boolean  是否显示点 
	 *   pointText:'文字'    string   代替点的文字,设置了则不显示点,需要把markPoint设为true  
	 * }]
	 * @param {Boolean} cover 是否覆盖原来的标记点
	 * @return none
	 * */
	setMark:function(data,cover){  
		if(cover){  //如果是覆盖标记点
			calendarWidget.config.mark = data;
			calendarWidget.renderCalendar();
			return;
		}
		
		if(data && data.length > 0){  //填充标记点
			for(var i = 0;i < data.length;i++){
				if(data[i] ==undefined){
					continue;
				}
				calendarWidget.config.mark.push(data[i])
				var selectDiv = $(".calendar-day").find('div[data-date="'+data[i].time+'"]');
				
				var tempTextStr = calendarWidget.config.formatText == undefined? data[i].text 
									: calendarWidget.config.formatText(data[i].text);
				
				if (tempTextStr != undefined && tempTextStr != ""){// 是否显示文字
					$(selectDiv).find('.calendar-text').html(tempTextStr);
				} 
				if(data[i].markPoint){// 是否显示点
					var pointTextStr = data[i].pointText? data[i].pointText : '●';
					$(selectDiv).find('.calendar-point').html(pointTextStr);
				}
			}
		}
	},
	/**
	 * 设置标记范围,初始化完成后可执行
	 * @param {string} startDate 开始时间 yyyy-MM-dd
	 * @param {string} endDate 结束时间 yyyy-MM-dd
	 * */
	setRange:function(startDate,endDate){  
		calendarWidget.range.start = undefined;
		calendarWidget.range.end = undefined;
		if(startDate && endDate){  //填充标记点
			startDate = startDate.replace(/-/g, "/");
			endDate = endDate.replace(/-/g, "/");
			var start = new Date(startDate);
			var end = new Date(endDate);
			calendarWidget.range.start =  new Date(startDate);
			calendarWidget.range.end = new Date(endDate);
			if(start == "Invalid Date" || end == "Invalid Date"){
				console.error('setRange : error param');
				return;
			}

			while(start <= end){
				var currentTimeStr = start.getFullYear() + "-" + (start.getMonth() + 1) + "-" + start.getDate();
				var selectDiv = $(".calendar-day").find('div[data-date="'+currentTimeStr+'"]');
				$(selectDiv).addClass("calendar-range");
				$(selectDiv).removeClass("calendar-active");
				start = start.setDate(start.getDate() + 1);
				start=new Date(start);
			}
		}
		else
			console.error('setRange : error param');
	},
	clearRange:function(){  //去掉范围标记
		calendarWidget.range.start = undefined;
		calendarWidget.range.end = undefined;
		$(".calendar-range").removeClass("calendar-range");
	},
	getTotalDay: function(time) { //获取月日期总数
		time = time.replace(/-/g, "/");
		var selectedDate = new Date(time);
		if(selectedDate == "Invalid Date"){
			selectedDate = new Date(time + "/01");
		}
		var selectedMonth = selectedDate.getMonth() + 1;
		selectedDate.setMonth(selectedMonth);
		selectedDate.setDate(0);
		var dayMany = selectedDate.getDate();

		return dayMany;
	},
	/**
	 * 设置日历的日期范围
	 * @param {string} startDate 开始时间 yyyy-MM-dd
	 * @param {string} endDate 结束时间 yyyy-MM-dd
	 * */
	setDateRange:function(startDate,endDate){
		//设置开始时间
		if(startDate){
			calendarWidget.config.startDate = new Date(startDate.replace(/-/g, "/")); 
			if(calendarWidget.config.startDate == "Invalid Date"){
				console.error('startDate config error');
				calendarWidget.config.startDate = undefined;
			}
		}
		
		//设置结束时间
		if(endDate){
			calendarWidget.config.endDate = new Date(endDate.replace(/-/g, "/")); 
			if(calendarWidget.config.endDate == "Invalid Date"){
				console.error('endDate config error');
				calendarWidget.config.endDate = undefined;
			}
		}
		
		calendarWidget.renderCalendar();
	}
}

样式:

.calendar-Time-header{
	/* border-top: 1px solid gainsboro; */
	text-align: center;
	min-height: 40px;
	padding: 10px;
}
.calendar-TimeH{
}
.calendar-lastMonth{
	width: 50px;
	font-size: 15px;
	margin-right: 10%;
	padding: 0 5px;
	/* float: left;	 */
	text-align: center;
}
.calendar-nextMonth{
	text-align: center;
	margin-left: 10%;
	font-size: 15px;
	padding: 0 5px;
 	/* float: right;	 */
}
.calendar-backToToday{
	text-align: center;
	font-size: 12px;
	position: absolute;	
	right: 5px;
}

.calendar-row:before,
.calendar-row:after {
	display: table;
	content: ' ';
}

.calendar-row:after {
	clear: both;
}

.calendar-col {
	border-radius: 3px;
	width: 14.285714%;
	position: relative;
	float: left;
	padding: 8px;
	min-height: 40px;
}

.aligncanter {
	text-align: center;
}

.calendar-header {
	color: gray;
	height: 40px;
	font-size: 12px;
	/* border-bottom: 1px solid gainsboro; */
}

.calendar-day {
	height: 40px;
	transform: translate3d(0px, 0px, 0px) translateZ(0px); transition-duration: 0ms; transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
}

.calendar-content {
}

.calendar-today {
	background-color: #43CD80;
	color:white;
	-moz-box-shadow: 0px 1px 5px #ABABAB;
	-webkit-box-shadow: 0px 1px 5px #ABABAB;
	box-shadow: 0px 1px 5px #ABABAB;
}

.calendar-active {
	color:#01AAED;
	background-color: #D9D9D9;
	-moz-box-shadow: 0px 1px 5px #ABABAB;
	-webkit-box-shadow: 0px 1px 5px #ABABAB;
	box-shadow: 0px 1px 5px #ABABAB;
}
/* 范围标记 */
.calendar-range {
	/* color:#01AAED; */
	border-radius: 0px;
	background-color: #D9D9D9;
	-moz-box-shadow: none;
	-webkit-box-shadow: none;
	box-shadow: none;
}


.ClearBoth {
	clear: both;
	/* border-top: 1px solid gainsboro; */
}
.calendar-col-nextMonth{
	color:gainsboro;
}
.calendar-col-lastMonth{
	color:gainsboro;
}
.calendar-point{
	font-size: 8px;color: #01AAED;top:0px;right: 1px;position: absolute;
}
.calendar-text{
	max-height:  .25rem;
	padding: .01rem;
	width:100%;font-size: .14rem;color: #01AAED;top:20px;left: 0px;position: absolute;overflow:hidden;
}
.dayValue{
	text-align: center;
}

.calendar-day-6-7{
	color: gray;
}


/* 以下为实现0.5px底部边界 */
.under_line{position: relative;}
.under_line:before,
.under_line:after{position: absolute;content: " ";height: 1px;width: 100%;left: 0;transform-origin: 0 0;-webkit-transform-origin: 0 0;}
/* .fineLine:before{顶部top: 0;background: #000;} */
.under_line:after{bottom: 0;border-bottom: 1px solid gainsboro;}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5){.under_line:after,.under_line:before{-webkit-transform: scaleY(.667);}}
@media only screen and (-webkit-min-device-pixel-ratio: 2){.under_line:after,.under_line:before{-webkit-transform: scaleY(.5);}}
/* 以上为实现0.5px底部边界 */

 

用法:

<div id='dateWidget' style='background-color: white;'></div>


calendarWidget.initCalculate({
			elem: "#dateWidget",
			currentTime: '2019-8-1',
			mark: [{
					time: '2019-8-5',
					text: '<span style="color:red">未排</span>',
					markPoint: true,
					pointText: '<span style="color:red">●</span>'
				}],
			mounted: function(data) { //初始化完成 
				console.log(data)
			},
			change: function(selectedDate, markPoint) {
				 
			},
			dateclick: function(widget, curentDate) { //点击顶部时间回调,方便外部设置时间
				 
			}
            formatText: function(text) { //格式化文本
				 
			}
		});

//设置范围
calendarWidget.setRange('2019-8-1', '2019-8-15');

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值