javascript画全年日历

2023-11-18

        前些日子闲聊群里有人提了用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()以下被点击的日期,这个自己根据业务需要实现。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

javascript画全年日历 的相关文章

  • 修改 Twitter 帖子上可编辑 Div 的内容

    我正在编写一个 chrome 扩展 它可以帮助用户在 Twitter 上输入内容 当在 twitter 上写推文时 twitter 会打开一个可编辑的 div 容器 当用户输入内容时 twitter 大概正在使用某些网络框架 会生成子 di
  • Python“非规范化”unicode 组合字符

    我正在寻找标准化 python 中的一些 unicode 文本 我想知道是否有一种简单的方法可以在 python 中获得组合 unicode 字符的 非规范化 形式 例如如果我有序列u o xaf i e latin small lette
  • PIL.Image.open和tf.image.decode_jpeg返回值的区别

    我使用 PIL Image open 和 tf image decode jpeg 将图像文件解析为数组 但发现PIL Image open 中的像素值与tf image decode jpeg不一样 为什么会出现这种情况 Thanks 代
  • 时间序列数据预处理 - numpy strides 技巧以节省内存

    我正在预处理一个时间序列数据集 将其形状从二维 数据点 特征 更改为三维 数据点 时间窗口 特征 在这样的视角中 时间窗口 有时也称为回顾 指示作为输入变量来预测下一个时间段的先前时间步长 数据点的数量 换句话说 时间窗口是机器学习算法在对
  • 非法使用break语句; javascript

    当这个变量达到一定数量时 我希望循环停止 但我不断收到错误 未捕获的语法错误 非法的中断语句 function loop if isPlaying jet1 draw drawAllEnemies requestAnimFrame loop
  • 为什么在Python解释器中输入_会返回True? [复制]

    这个问题在这里已经有答案了 我的翻译行为非常奇怪 gt gt gt True gt gt gt type True
  • D3 向对象添加超链接?

    我正在尝试制作 D3 图 它将代表我网站的菜单 我尝试按照此处的其他指南添加超链接 但它们都不起作用 每个对象都会有一个不同的 URL 指向 主页 关于 联系方式等 如果添加超链接 我可以拖动对象吗 这意味着如果我按住单击 如果我单击该对象
  • 引用自身的 Javascript 对象...有问题吗?

    由于 Javascript 允许通过引用分配复合值 因此如果 Javascript 对象引用自身 它将创建无限的引用集 如控制台中所示 这看起来像是某种无限循环 但 Chrome 似乎没有问题 这样做是否存在任何内存问题或其他风险 就记忆力
  • 如何在新窗口中打开图像或pdf文件?

    我有一个 gridview 它包含文件名和文件路径 图像和 pdf 格式文件 其中我使用了模板字段 在该字段下放置了 1 个图像按钮 单击该图像按钮 即 查看 按钮 时 我想在新窗口中打开所选文件 这是我的代码 protected void
  • 将字符串中的随机字符转换为大写

    我尝试随机附加文本字符串 这样就不只是有像这样的输出 gt gt gt david 我最终会得到类似的东西 gt gt gt DaViD gt gt gt dAviD 我现在的代码是这样的 import random import stri
  • AngularStrap 工具提示禁用我的自定义指令

    我正在尝试让 bs tooltip AngularStrap 指令与我自己的名为 checkStrength 的自定义指令一起使用 该指令检查密码的强度 单独使用这些指令中的任何一个时 它们都可以正常工作 但不能一起工作 This http
  • 如何使用 jQuery 单击特定链接时打开引导导航选项卡的特定选项卡?

    我是 jquery 和 bootstrap 的新手 所以请考虑我的错误 我已经创建了一个用于登录和注册的 bootstrap 模式 它包含两个导航选项卡 称为登录和注册 我有两个按钮可以弹出相同的模态窗口 但在模态窗口内显示不同的选项卡 每
  • numpy polyfit 中使用的权重值是多少以及拟合误差是多少

    我正在尝试对 numpy 中的某些数据进行线性拟合 Ex 其中 w 是该值的样本数 即对于点 x 0 y 0 我只有 1 个测量值 该测量值是2 2 但对于这一点 1 1 我有 2 个测量值 值为3 5 x np array 0 1 2 3
  • 如何使用 javascript 更改文件扩展名

    有谁知道在 Javascript 中更改文件扩展名的简单方法吗 例如 我有一个带有 first docx 的变量 但我需要将其更改为 first html 这将改变字符串包含文件名 let file first docx file file
  • 使用 File API polyfill 读取数据 URL

    我正在尝试使用文件 API 库 https github com mailru FileAPI https github com mailru FileAPI 作为不支持文件 API 的浏览器的后备 以便将文件作为数据 URL 读取并将其传
  • 如何为 jQuery 插件设置私有变量?

    我想创建一个简单的插件 它使用元素的文本作为默认值 或者您可以在调用插件时设置此值 但是 如果我不设置该值 并为多个元素调用插件 则默认值会成倍增加 function fn reText function options var setti
  • Jupyter Notebook:带有小部件的交互式绘图

    我正在尝试生成一个依赖于小部件的交互式绘图 我遇到的问题是 当我使用滑块更改参数时 会在前一个绘图之后完成一个新绘图 而我预计只有一个绘图会根据参数发生变化 Example from ipywidgets import interact i
  • 区分 NaN 输入和输入类型为“number”的空输入

    我想使用 type number 的表单输入 并且只允许输入数字
  • 如何通过点击复制 folium 地图上的标记位置?

    I am able to print the location of a given marker on the map using folium plugins MousePosition class GeoMap def update
  • 描述符“join”需要“unicode”对象,但收到“str”

    代码改编自here http wiki geany org howtos convert camelcase from foo bar to Foo Bar def lower case underscore to camel case s

随机推荐

  • llama2模型部署方案的简单调研-GPU显存占用(2023年7月25日版)

    先说结论 全精度llama2 7B最低显存要求 28GB 全精度llama2 13B最低显存要求 52GB 全精度llama2 70B最低显存要求 280GB 16精度llama2 7B预测最低显存要求 14GB 16精度llama2 13
  • three.js 楼层加载动画

    three js 楼层加载动画 概述 创建场景 创建天空 创建水面 创建模型 开启模型动画 栅栏动画 概述 如有不明白的可以加QQ 2354528292 wx aichitudousien 更多教学视频请访问 https space bil
  • 跋20230325

    很久没有登录csdn 突然上号一次发现n多的评论和私信 时间跨度从2021年到2023年 感谢大家的信任 但是消息太多 且现在笔者已经没有从事相关行业 大家的问题很有深度 都是我答不上来的 这里就不一 一进行回复了 请大佬们见谅 博文都是笔
  • java字符串基础操作

    1 字符串的特点 java lang String使用了final修饰 不能被继承 字符串底层封装了字符数组及针对字符数组的操作算法 字符串一旦创建 对象内容永远无法改变 但字符串引用 可以重新赋值 Java字符串在内存中采用Unicode
  • 今天发现rabbitMQ消息堆积

    发现有三十多万的消息堆积在10的queue里没有被消费 记录一下查看问题的步骤 1 jps 找出程序的PID 2 jstack PID 查看线程dump 发现rabbitMQ的consumer worker线程block住了 Thread
  • 转眼就来字节六个月了,真的不一样

    今天来分享一个学弟 也是我老乡 阿秀 他入职字节跳动 6 个月的感受 希望给向往大厂的小伙伴一点点信心和动力 一 过去 首先来回复下有些小伙伴对字节存在的疑问 1 字节 996 的生活长期来看没有啥意义 我觉得还是挺有意义的 因为见识到了自
  • 前后端分离总结(部分)

    本文内容转载于博客 前后端分离架构概述 https blog csdn net fuzhongmin05 article details 81591072 1 背景 前后端分离已成为互联网项目开发的业界标准使用方式 通过nginx tomc
  • Springboot中使用netty 实现 WebSocket 服务

    依赖
  • C语言:写文件

    C语言 写文件 在C语言中 我们可以使用标准库函数来创建 打开 写入和关闭文件 文件操作是处理数据的重要方面之一 它允许我们将数据永久保存在磁盘上 并在需要时进行读取和修改 本文将介绍如何在C语言中写入文件 并提供相应的源代码示例 首先 我
  • [Dynamics CRM]错误代码参考

    转载于 http it zhaozhao info archives 20266 0x80048472 One or more imports are not in completed state Imported records can
  • 【Darknet】模型隐藏的一种方法

    之前在一个公司实习的时候有个需求 说要把Darknet的模型隐藏起来 就是说提供给用户的只有dll 而cfg和weights文件不能直接给客户 不然就暴露商业机密了嘛 所以就研究了一下如何隐藏模型 主要参考这篇文章 具体原理咱也不是很懂 反
  • 微信小程序使用AES加密和解密

    前端请求后端接口进行参数加密处理 const CryptoJs require crypto js const defaultKey zoe nurse qazxr8 默认的key const defaultIv qwertyuiopasd
  • [性能测试]LR常见问题整理

    1 LR 脚本为空的解决方法 1 去掉ie设置中的第三方支持取消掉 2 在系统属性 高级 性能 数据执行保护中 添加loadrunner安装目录中的vugen exe文件 有可能是由于录制的URL地址采用的是localhost的问题 改成分
  • centos系统服务器脚本,CentOS使用脚本管理服务的详解

    1 使用工具 chkconfig 管理 etc rc d init d或 etc init d 目录下的服务启动脚本 要在服务启动脚本开头添加两行 chkconfig 2345 88 12 description XXXXXXXXX XXX
  • 群晖NAS报“发生网络错误。请检查DNS和网络设置”的解决方法

    如标题中所述 新买的群晖DNS 登录Synology账号 设置所谓的QuickConnect的时候就会报这种错误 尝试了一下 控制面板 网络 手动配置DNS服务器 填入 180 76 76 76 再进行类似如图所示的设置即可 呵呵 貌似这个
  • 可能是全网最清晰的KMP算法讲解

    字符串匹配 字符串A是否为字符串B的子串 如果是 出现在B的什么位置 这个问题就是字符串匹配问题 字符串A称为模式串 字符串B称为主串 那么 如何查找模式串在主串中的位置呢 暴力匹配 暴力匹配 顾名思义 是一种简单粗暴的匹配方法 从主串的第
  • ubuntu上安装微信

    一 下载安装Wine环境包 http archive ubuntukylin com software pool partner ukylin wine 70 6 3 25 amd64 deb 二 下载安装微信包 http archive
  • Oracle:修改表空间和数据文件的名称

    1 修改表空间名称 alter tablespace tablespace name1 rename to tablespace name2 2 修改数据文件名称 1 先将联机状态的需要修改的表空间设置为脱机状态 ALTER TABLESP
  • 解决Value '0000-00-00 ' can not be represented as java.sql.Timest

    在使用MySql 时 数据库中的字段类型是timestamp的 默认为0000 00 00 会发生异常 java sql SQLException Value 0000 00 00 can not be represented as jav
  • javascript画全年日历

    前些日子闲聊群里有人提了用js画全年日历的需求 趁闲暇时间画了个小demo 下面还是先上效果图吧 高亮显示的是今天的日期和标记要高亮显示的日期 也添加了点击事件的钩子 自己可以实现钩子函数 从而操作点击的日期值 下面还是先上dai 日历视图