热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JS学习之一个简易的日历控件_时间日期

这种日历控件实现起来不难,下面简单分析下我的思路
这个日历控件类似于园子用的日历,如下图:

js 简易的日历控件

这种日历控件实现起来不难,下面简单分析下我的思路:

首先,是该控件的可配置项:

代码如下:


...
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("");
ht.push("

<

", year, "年", month, "月

>

");
ht.push("");
//星期
ht.push("");
for (var i = 0; i <7; i++) {
var day = (i + this.settings.firstDayOfWeek) == 7 ? 7 : (i + this.settings.firstDayOfWeek) % 7;
ht.push("", this.weekDayNames[day], "")
}
ht.push("");
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("");
}
ht.push("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 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("");
if (i % 7 == 6) {//结束一行
ht.push("");
}
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 (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 if (Date.parse(this.dateLinkMappings[j].Date) - curDate == 0) {
ht.push("", curDate.getDate(), "");
break;
}
}
if (j == this.dateLinkMappings.length) {
ht.push(curDate.getDate());
}
}
else {
ht.push(" ");
}
return ht.join("");
},


事实上本日历控件的意图是用户可以在初始化时传入日期和该日期对应的链接的映射的数组,也就是this.dateLinkMappings,当构建单元格时若正在构建的日期包含在this.dateLinkMappings里,则将当前单元格构造成形式,否则为普通的文本形式。

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());


打包下载地址
推荐阅读
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 本文介绍了一种图片处理应用,通过固定容器来实现缩略图的功能。该方法可以实现等比例缩略、扩容填充和裁剪等操作。详细的实现步骤和代码示例在正文中给出。 ... [详细]
  • 本文介绍了Cocos2dx学习笔记中的更新函数scheduleUpdate、进度计时器CCProgressTo和滚动视图CCScrollView的用法。详细介绍了scheduleUpdate函数的作用和使用方法,以及schedule函数的区别。同时,还提供了相关的代码示例。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 前言对于从事技术的人员来说ajax是这好东西,都会使用,而且乐于使用。但对于新手,开发一个ajax实例,还有是难度的,必竟对于他们这是新东西。leo开发一个简单的ajax实例,用的是 ... [详细]
  • 表单提交前的最后验证:通常在表单提交前,我们必须确认用户是否都把必须填选的做了,如果没有,就不能被提交到服务器,这里我们用到表单的formname.submit()看演示,其实这个对于我们修炼道 ... [详细]
  • Itwasworkingcorrectly,butyesterdayitstartedgiving401.IhavetriedwithGooglecontactsAPI ... [详细]
  • Iwouldliketobeabletohaveasidebarthatcanbetoggledinandoutonabuttonpress.However ... [详细]
  • 但有时候,需要当某事件触发时,我们先做一些操作,然后再跳转,这时,就要用JAVASCRIPT来实现这一跳转功能。下面是具体的做法:一:跳转到新页面,并且是在新窗口中打开时:复制代码代码如下:fu ... [详细]
  • JavaScript在常人看来都是门出不了厅堂的小语言,仅管它没有明星语言的闪耀,但至少网页的闪耀还是需要它的,同时它是一门很实用的语言,本人平时就喜欢拿它来写点实用工具或应用,本文演示用JavaSc ... [详细]
  • JavaScript概述1.JavaScript定义JavaScript是Netscape公司开发的一种基于对象和事件驱动的脚本语言。它是弱类型语言,只能由浏览器解释执行。其中:脚本语言:解释运行( ... [详细]
  • 本文介绍了Java的公式汇总及相关知识,包括定义变量的语法格式、类型转换公式、三元表达式、定义新的实例的格式、引用类型的方法以及数组静态初始化等内容。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 本文介绍了Python函数的定义与调用的方法,以及函数的作用,包括增强代码的可读性和重用性。文章详细解释了函数的定义与调用的语法和规则,以及函数的参数和返回值的用法。同时,还介绍了函数返回值的多种情况和多个值的返回方式。通过学习本文,读者可以更好地理解和使用Python函数,提高代码的可读性和重用性。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
author-avatar
王先生
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有