时间:2021-05-26
这个日历控件类似于园子用的日历,如下图:
这种日历控件实现起来不难,下面简单分析下我的思路:
首先,是该控件的可配置项:
复制代码 代码如下:
...
settings:
{
firstDayOfWeek: 1,
baseClass: "calendar",
curDayClass: "curDay",
prevMonthCellClass: "prevMonth",
nextMonthCellClass: "nextMonth",
curMonthNormalCellClass: "",
prevNextMonthDaysVisible: true
},
...
weekDayNames: [],
...
其中有一半是用来控制单元格样式的(不做过多描述),另外几个(firstDayOfWeek,prevNextMonthDaysVisible,weekDayNames),意义如下:
firstDayOfWeek:日历以星期几做为第一天
prevNextMonthDaysVisible:是否显示本月之外的日期
weekDayNames:星期的名称(一个索引从1开始的数组,1处的值将作为周一的显示名称,以此类推)
接下来,进入生成html代码阶段:
1.生成日历头:
复制代码 代码如下:
_RenderTitle: function(month, year) {
var ht = [];
//日期
ht.push("<tr>");
ht.push("<th colspan='7' style='width:100%;'><div style='float:left;width:10%;text-align:center;' id='", this.containerId, "_prevMonth' title='上一月'><</div><div style='float:left;text-align:center;width:80%'>", year, "年", month, "月</div><div style='float:right;width:10%; text-align:center;' id='", this.containerId, "_nextMonth' title='下一月'>></div></th>");
ht.push("</tr>");
//星期
ht.push("<tr>");
for (var i = 0; i < 7; i++) {
var day = (i + this.settings.firstDayOfWeek) == 7 ? 7 : (i + this.settings.firstDayOfWeek) % 7;
ht.push("<th>", this.weekDayNames[day], "</th>")
}
ht.push("</tr>");
return ht.join("");
},
日期部分为操作‘按钮'的id使用日历控件容器的id 作为前缀,以保证id唯一。
星期部分根据firstDayOfWeek的设置来获取weekDayName。这里关键在于判断每个单元格代表星期几,思路很简单:
var day = (i + this.settings.firstDayOfWeek) == 7 ? 7 : (i + this.settings.firstDayOfWeek) % 7;
这样就可以取得当前单元格代表的星期了。
2.生成日历的主要部分:
复制代码 代码如下:
_RenderBody: function(month, year) {
var date = new Date(year, month - 1, 1);
var day = date.getDay();
var dayOfMonth = 1;
var daysOfPrevMonth = (7 - this.settings.firstDayOfWeek + day) % 7;
var totalDays = this._GetTotalDays(month, year);
var totalDaysOfPrevMonth = this._GetToalDaysOfPrevMonth(month, year);
var ht = [];
var curDate;
for (var i = 0; ; i++) {
curDate = null;
if (i % 7 == 0) {//新起一行
ht.push("<tr>");
}
ht.push("<td");
if (i >= daysOfPrevMonth && dayOfMonth <= totalDays) {//本月
curDate = new Date(year, month - 1, dayOfMonth);
if (Date.parse(new Date().toDateString()) - curDate == 0) {
ht.push(" class='", this.settings.curDayClass, "'");
}
else {
ht.push(" class='", this.settings.curMonthNormalCellClass, "'");
}
dayOfMonth++;
}
else if (i < daysOfPrevMonth) {//上月
if (this.settings.prevNextMonthDaysVisible) {
var prevMonth = month;
var prevYear = year;
if (month == 1) {
prevMonth = 12;
prevYear = prevYear - 1;
}
else {
prevMonth = prevMonth - 1;
}
curDate = new Date(prevYear, prevMonth - 1, totalDaysOfPrevMonth - (daysOfPrevMonth - i - 1));
ht.push(" class='", this.settings.prevMonthCellClass, "'");
}
}
else {//下月
if (this.settings.prevNextMonthDaysVisible) {
var nextMonth = month;
var nextYear = year;
if (month == 12) {
nextMonth = 1;
nextYear = prevYear + 1;
}
else {
nextMonth = nextMonth + 1;
}
curDate = new Date(nextYear, nextMonth-1, i - dayOfMonth - daysOfPrevMonth + 2);
ht.push(" class='", this.settings.nextMonthCellClass, "'");
}
}
ht.push(">");
ht.push(this._BuildCell(curDate));
ht.push("</td>");
if (i % 7 == 6) {//结束一行
ht.push("</tr>");
}
if (i % 7 == 6 && dayOfMonth - 1 >= totalDays) {
break;
}
}
return ht.join("");
},
(1).获取该月一号代表星期几。这样才能判断1号应该放到哪个单元格,也就是该月从哪个单元格开始(创建日期的时候month减了1,这是由于js Date对象本身的特性)。
(2).定义了一个标识变量 dayOfMonth ,用于控制本月日期显示区域。
(3).计算要展示的上月的天数以及上月的总天数(不用计算下月要展示的天数和总天数,因为下月要展示的日期是从1开始,最多不会超过6)。
(4).显示本月的日期:
条件i >= daysOfPrevMonth && dayOfMonth <= totalDays决定了本月日期的显示区域。
(5).显示上月日期:
当i < daysOfPrevMonth 时即为上月日期的显示区域。
(6). (4)、(5)之外当然就是下月日期的显示区域了。
(7).何时结束:
从代码看到for循环是没有终止条件的,因此必须自己决定何时退出循环:
复制代码 代码如下:
if (i % 7 == 6 && dayOfMonth - 1 >= totalDays) {
break;
}
i % 7 == 6表示一行结束, dayOfMonth - 1 >= totalDays表示本月日期已经展示完毕。
(8).构造curDate:
curDate代表每个单元格对应的日期。
在显示本月日期时, curDate = new Date(year, month - 1, dayOfMonth);
在显示上月日期时, curDate = new Date(prevYear, prevMonth-1, totalDaysOfPrevMonth - (daysOfPrevMonth - i - 1));
在显示下月日期时, curDate = new Date(nextYear, nextMonth-1, i - dayOfMonth - daysOfPrevMonth + 2),加2是由于i是从0开始,本身就少了1,dayOfMonth 在退出显示本月日期时多加了一次.
最后,再来看看_BuildCell做了什么事情:
复制代码 代码如下:
_BuildCell: function(curDate) {
var ht = [];
if (curDate) {
for (var j = 0; j < this.dateLinkMappings.length; j++) {
if (Date.parse(this.dateLinkMappings[j].Date) - curDate == 0) {
ht.push("<a href='", this.dateLinkMappings[j].Link, "'>", curDate.getDate(), "</a>");
break;
}
}
if (j == this.dateLinkMappings.length) {
ht.push(curDate.getDate());
}
}
else {
ht.push(" ");
}
return ht.join("");
},
事实上本日历控件的意图是用户可以在初始化时传入日期和该日期对应的链接的映射的数组,也就是this.dateLinkMappings,当构建单元格时若正在构建的日期包含在this.dateLinkMappings里,则将当前单元格构造成<a>形式,否则为普通的文本形式。
OK,实现逻辑大致如此,篇末看下演示效果:
前台调用代码如下:
复制代码 代码如下:
var date = new Date();
var mapping = [];
mapping.push(new DateLinkMapping("3-22-2010", "javascript:alert(1)"));
mapping.push(new DateLinkMapping("4-1-2010", "javascript:alert(1)"))
Calendar.Init(null, mapping);
Calendar.RenderCalendar("myCalendar", date.getMonth() + 1, date.getFullYear());
打包下载地址
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
项目中需要用到日历,.net的日历控件又太重,只好用js写一个,日历的核心函数是DateAdd(),编写过程中发现js里面操作时间比想象中的繁琐,不像vbscr
一个日历控件,这是官方说明,,供大家参考,具体内容如下首先引入css样式html标签引入js文件javascript显示日历$("#dateTime").dat
最近看了一下关于js日期的一些函数,突然想到了日历控件,于是试着写了一个,作为后台程序员的我水平有限,大家抱着学习的态度看看我写的这个例子吧,一起学习进步!首先
本文为大家分享了一个炫酷的js日历控件,供大家参考,具体内容如下引用JSLit.js下载JSLite.io,兼容JSLite和jQuery安装方法页面引用JSL
之前项目中有用到日历控件,当时由于时间问题,是在网上找到一个demo,然后二次开发的,从那时就想着自己写一个日历控件。这篇文章说明日历数据的处理,去除月份天数判