javascript画全年日历

        前些日子闲聊群里有人提了用js画全年日历的需求,趁闲暇时间画了个小demo,下面还是先上效果图吧。

        高亮显示的是今天的日期和标记要高亮显示的日期,也添加了点击事件的钩子,自己可以实现钩子函数,从而操作点击的日期值。

下面还是先上dai

/**
 * 日历视图
 */
class DateView{
	/**
	 * [constructor 构造]
	 * @param  {[type]} option [description]
	 * @return {[type]}        [description]
	 */
	constructor(option){
		this.FtColor=option?.FtColor==undefined?"#000":option?.FtColor;
		this.BdColor=option?.BdColor==undefined?"#fff":option?.BdColor;
		this.BgColor=option?.BgColor==undefined?"#fff":option?.BgColor;
		this.FtSize=option?.FtSize==undefined?"30px":option?.FtSize;
		this.padding=option?.padding==undefined?"10px":option?.padding;
		this.parent=option?.parent==undefined?"body":option?.parent;
		this.index=0;
	}
	/**
	 * [setFtColor 设置字体颜色]
	 * @param {[type]} FtColor [description]
	 */
	setFtColor(FtColor){
		this.FtColor=FtColor;
		return this;
	}
	/**
	 * [setBdColor 设置边框颜色]
	 * @param {[type]} BdColor [description]
	 */
	setBdColor(BdColor){
		this.BdColor=BdColor;
		return this;
	}
	/**
	 * [setBgColor 设置背景颜色]
	 * @param {[type]} BgColor [description]
	 */
	setBgColor(BgColor){
		this.BgColor=BgColor;
		return this;
	}
	/**
	 * [setFtSize 设置字体大小]
	 * @param {[type]} FtSize [description]
	 */
	setFtSize(FtSize){
		this.FtSize=FtSize;
		return this;
	}
	/**
	 * [setPadding 设置padding]
	 * @param {[type]} padding [description]
	 */
	setPadding(padding){
		this.padding=padding;
		return this;
	}
	/**
	 * [setParent 设置日历容器]
	 * @param {[type]} parent [description]
	 */
	setParent(parent){
		this.parent=parent;
		return this;
	}
	/**
	 * [drawDateByMonth 取得某一月的日历视图]
	 * @param  {[type]} yearOrmonth [年或月]
	 * @param  {[type]} Month       [月]
	 * @param  {[type]} callBack    [钩子函数,点击日期后的动作]
	 * @param  {[type]} width       [控件宽度]
	 * @param  {[type]} tagData     [需要高亮显示的日期数据如['2023.1.12','2023.1.13']]
	 * @return {[type]}             [description]
	 */
	drawDateByMonth(yearOrmonth,Month,callBack,width,tagData){
		let date=new Date();
		let year,month;
		if(yearOrmonth==undefined){
			year=date.getFullYear();
			month=date.getMonth()+1;
		}else if(yearOrmonth!=undefined&&yearOrmonth>12){
			year=yearOrmonth;
			if(Month==undefined){
				throw new Error("缺少参数“月份”");
			}
			month=Month;
		}else{
			year=date.getFullYear();
			month=yearOrmonth;
		}
		if(year<1900||year>2100){
			throw new Error("年份超出了限定区间1900-2100");
		}
		let html=`<style>
			.dateView${this.index}{
				position: relative;
				${width};
				margin-left:10px;
				color:${this.FtColor};
				font-size: ${this.FtSize};
				background: ${this.BdColor};
				display:inline-block;
				vertical-align:top;
				padding:10px;
			}
			.dateView${this.index} tr{
				background: ${this.BdColor};
			}
			.dateView${this.index} tr td{
				background: ${this.BgColor};
				padding: ${this.padding};
				cursor:pointer;
			}
			.dateView${this.index}Tag{
				color:${this.BgColor};
				background: ${this.FtColor} !important;
			}
		</style>
		<table class="dateView${this.index}">
		<tr>
			<td colspan="7">${month}月</td>
		</tr>
		<tr>
			<td>一</td><td>二</td><td>三</td><td>四</td><td>五</td><td>六</td><td>七</td>
		</tr>`;

		let days=this.getDaysByYearAndMonth(year,month);//本月多少天
		let firstDay=new Date(year+"/"+month+"/1 1:1:1").getDay();//本月第一天是星期几
		firstDay=firstDay==0?6:firstDay-1;
		let weeks=Math.ceil((days+firstDay)/7);//本月有几周
		let dateArr=[];
		for(var i=1;i<weeks*7+1;i++){
			if((i-firstDay<=0)||(i-firstDay>days)){
				dateArr.push("");
			}else{
				dateArr.push(i-firstDay);
			}
		}
		function splitArray(array, size){
		  let data = [];
		  for (let i = 0; i < array.length; i += size) {
		    data.push(array.slice(i, i + size))
		  }
		  return data
		}
		dateArr=splitArray(dateArr,7);
		tagData=tagData==undefined?[]:tagData;
		let today=new Date();
		today=today.getFullYear()+"-"+(today.getMonth()+1)+"-"+today.getDate();
		tagData.push(today);
		for(var i in dateArr){
			html+=`<tr>`;
			for(var j in dateArr[i]){
				var t=`${year}-${month}-${dateArr[i][j]}`;
				if(tagData.indexOf(t)>=0){
					html+=`<td class="dateView${this.index}Tag" t="${t}">${dateArr[i][j]}</td>`;
				}else{
					html+=`<td t="${t}">${dateArr[i][j]}</td>`;
				}
			}
			html+=`</tr>`;
		}
		if(this.parent=="body"){
			document.body.insertAdjacentHTML("beforeend",html);
		}else{
			document.querySelector(this.parent).insertAdjacentHTML("beforeend",html);
		}
		if(callBack!=undefined){
			document.querySelector(`.dateView${this.index}`).addEventListener('click',function(e){
				if(e.target.getAttribute("t")!=null){
					callBack(e.target.getAttribute("t"));
				}
			});
		}
		
		this.index++;
	}
	/**
	 * [getDaysByYearAndMonth 根据年月取得月份的天数]
	 * @param  {[type]} year  [年]
	 * @param  {[type]} month [月]
	 * @return {[type]}       [description]
	 */
	getDaysByYearAndMonth(year,month){
		if([1,3,5,7,8,10,12].indexOf(month)>=0){
			return 31;
		}else if(month==2){
			if(year%100==0){
				if(year%400==0){
					return 29;
				}else{
					return 28;
				}
			}else{
				if(year%4==0){
					return 29;
				}else{
					return 28;
				}
			}
		}else{
			return 30;
		}
	}
	/**
	 * [drawDateByYear 画出某一年全年的日历]
	 * @param  {[type]} year     [年]
	 * @param  {[type]} cols     [一行显示几个月份]
	 * @param  {[type]} callBack [钩子函数,点击日期后的动作]
	 * @param  {[type]} tagData  [需要高亮显示的日期数据如['2023.1.12','2023.1.13']]
	 * @return {[type]}          [description]
	 */
	drawDateByYear(year,cols,callBack,tagData){
		year=year==undefined?new Date().getFullYear():year;
		cols=cols==undefined?5:cols;
		let width="width:"+Math.floor(100/cols-1)+"%";
		console.log(width)
		for(var i=1;i<=12;i++){
			this.drawDateByMonth(year,i,callBack,width,tagData);
		}
	}
}




let d=new DateView({
	FtSize:"20px",
	FtColor:"#123ae3"
});
d.drawDateByYear(2023,5,function(v){
	alert(v);
},[
	'2023-10-13',
	'2023-9-26',
	'2023-10-12'
]);

使用也很简单,本文开始的效果图,实现代码如下

let d=new DateView({
	FtSize:"20px",
	FtColor:"#123ae3"
});
d.drawDateByYear(2023,5,function(v){
	alert(v);
},[
	'2023-10-13',
	'2023-9-26',
	'2023-10-12'
]);

 其中FtSize为字体大小,Ftcolor为字体颜色,具体设置看构造函数,也有单独的设置字体大小颜色等配置的函数,通过链式操作即可,例如

let d=new DateView({
    FtSize:"20px",
    FtColor:"#123ae3"
});

也可以写成

let d=new DateView();

d.setFtColor("#123ae3").FtSize("20px");

或者也可以不传入任何参数,将默认输出黑白日历

drawDateByYear()方法画出全年的日历,也可以用drawDateByMonth()方法画出某个月的单月日历,默认将日历dom插入到body里,也可以通过传入parent修改日历容器,例如某个div,d.drawDateByYear(2023,5,function(v){
    alert(v);
},[
    '2023-10-13',
    '2023-9-26',
    '2023-10-12'
]);

其中这个匿名函数

function(v){
    alert(v);
}为点击回调的钩子函数,这个是点击相应日期后alert()以下被点击的日期,这个自己根据业务需要实现。

后面这个数组就是要高亮显示的日期

代码都有注释,比较明了了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值