JavaScript blog式日历控件javascript

javascript blog式日历控件

近来要做一个记事本系统,想找一个合适的日历控件,但网上的都是那种日历选择控件。

于是到qq的记事本系统找了一个,但里面的算法有点落后,所以用了它的样式自己写了个。

效果:

>

年 月

程序说明

【date】

这个日历控件运用了很多date相关操作和方法。

先说说date对象几个有用的属性:

getfullyear:返回年份值

getmonth:返回月份值

getdate:返回一个月中的日期值

getday:返回一周中的日期值

其中对getday可能比较陌生,下面列出值对应的星期:

值 星期

0 星期天

1 星期一

2 星期二

3 星期三

4 星期四

5 星期五

6 星期六

这几个属性都是根据本地时间获取的,还有getutcfullyear、getutcmonth、getutcdate、getutcday这几个属性是全球标准时间对应的值。

下面说说获取日期对象,获取当前日期很简单:

new date()

获取指定日期:

new date(this.options.selectday)

获取指定年月日的日期:

new date(this.year, this.month - 1, d)

下面是几个比较有技巧的地方:

首先,做日历控件时需要知道该月第一天离星期天的天数,参照getday对应值,发现这刚好等于该月第一天的getday值,所以可以这样获得:

new date(this.year, this.month - 1, 1).getday()

还有是获取该月的天数,这里比较精妙,通过获取该月最后一天的getdate值就可以得到该月的天数,但没有办法直接获取该月最后一天。

这里有一个方法,当获取指定年月日的日期时,设置日参数为0,就可以获取上一个月的最后一天,所以可以这样获取:

new date(this.year, this.month, 0).getdate()

这个方法是很久以前在别人代码中发现的。

使用说明:

首先是实例化一个calendar,并设置参数。

参数说明:

year:要显示的年份

month:要显示的月份

selectday:选择日期

onselectday:在选择日期触发

ontoday:在当天日期触发

onfinish:日历画完后触发

一般selectday设置成选择了的日期,并在onselectday中设置一个函数用来设置这个日期的样式,

例如实例里selectday设置成今个月10号并在那天样式设为onselect:

selectday: new date().setdate(10),

onselectday: function(o){ o.classname = "onselect"; },

而ontoday就用来设置今日日期的样式,

例如实例里面把今天的日期的样式设为ontoday:

ontoday: function(o){ o.classname = "ontoday"; },

在onfinish中可以放需要设置日历的程序。

可以通过this.year和this.month获取当前日历显示的年份和月份。

对有数据的日期的也在这里设置,例如实例中是有一个当前月份的有数据的日期列表,然后根据这个列表对相应的日期进行设置:

code

var flag = [10,15,20];

for(var i = 0, len = flag.length; ilen; i++){

this.days[flag[i]].innerhtml = ""alert('日期是:"+this.year+"/"+this.month+"/"+flag[i]+"');return false;\">" + flag[i] + "";

}

实例中是固定了这个日期列表,实际应用中可以根据年份月份获取对应的日期列表,

个人推荐用年份月份通过ajax获取。

程序还有下面这几个方法:

nowmonth:显示当前月

premonth:显示上一月

nextmonth:显示下一月

preyear:显示上一年

nextyear:显示下一年

predraw:根据日期参数画日历

程序代码:

code

var $ = function (id) {

return "string" == typeof id ? document.getelementbyid(id) : id;

};

var class = {

create: function() {

return function() {

this.initialize.apply(this, arguments);

}

}

}

var extend = function(destination, source) {

for (var property in source) {

destination[property] = source[property];

}

return destination;

}

var calendar = class.create();

calendar.prototype = {

initialize: function(container, options) {

this.container = $(container);//容器(table结构)

this.days = [];//日期对象列表

this.setoptions(options);

this.year = this.options.year || new date().getfullyear();

this.month = this.options.month || new date().getmonth() + 1;

this.selectday = this.options.selectday ? new date(this.options.selectday) : null;

this.onselectday = this.options.onselectday;

this.ontoday = this.options.ontoday;

this.onfinish = this.options.onfinish;

this.draw();

},

//设置默认属性

setoptions: function(options) {

this.options = {//默认值

year:0,//显示年

month:0,//显示月

selectday:null,//选择日期

onselectday:function(){},//在选择日期触发

ontoday:function(){},//在当天日期触发

onfinish:function(){}//日历画完后触发

};

extend(this.options, options || {});

},

//当前月

nowmonth: function() {

this.predraw(new date());

},

//上一月

premonth: function() {

this.predraw(new date(this.year, this.month - 2, 1));

},

//下一月

nextmonth: function() {

this.predraw(new date(this.year, this.month, 1));

},

//上一年

preyear: function() {

this.predraw(new date(this.year - 1, this.month - 1, 1));

},

//下一年

nextyear: function() {

this.predraw(new date(this.year + 1, this.month - 1, 1));

},

//根据日期画日历

predraw: function(date) {

//再设置属性

this.year = date.getfullyear(); this.month = date.getmonth() + 1;

//重新画日历

this.draw();

},

//画日历

draw: function() {

//用来保存日期列表

var arr = [];

//用当月第一天在一周中的日期值作为当月离第一天的天数

for(var i = 1, firstday = new date(this.year, this.month - 1, 1).getday(); ifirstday; i++){ arr.push(0); }

//用当月最后一天在一个月中的日期值作为当月的天数

for(var i = 1, monthday = new date(this.year, this.month, 0).getdate(); imonthday; i++){ arr.push(i); }

//清空原来的日期对象列表

this.days = [];

//插入日期

var frag = document.createdocumentfragment();

while(arr.length){

//每个星期插入一个tr

var row = document.createelement("tr");

//每个星期有7天

for(var i = 1; i7; i++){

var cell = document.createelement("td"); cell.innerhtml = " ";

if(arr.length){

var d = arr.shift();

if(d){

cell.innerhtml = d;

this.days[d] = cell;

var on = new date(this.year, this.month - 1, d);

//判断是否今日

this.issame(on, new date()) && this.ontoday(cell);

//判断是否选择日期

this.selectday && this.issame(on, this.selectday) && this.onselectday(cell);

}

}

row.appendchild(cell);

}

frag.appendchild(row);

}

//先清空内容再插入(ie的table不能用innerhtml)

while(this.container.haschildnodes()){ this.container.removechild(this.container.firstchild); }

this.container.appendchild(frag);

//附加程序

this.onfinish();

},

//判断是否同一日

issame: function(d1, d2) {

return (d1.getfullyear() == d2.getfullyear() && d1.getmonth() == d2.getmonth() && d1.getdate() == d2.getdate());

}

}

测试代码:

code

var cale = new calendar("idcalendar", {

selectday: new date().setdate(10),

onselectday: function(o){ o.classname = "onselect"; },

ontoday: function(o){ o.classname = "ontoday"; },

onfinish: function(){

$("idcalendaryear").innerhtml = this.year; $("idcalendarmonth").innerhtml = this.month;

var flag = [10,15,20];

for(var i = 0, len = flag.length; ilen; i++){

this.days[flag[i]].innerhtml = ""alert('日期是:"+this.year+"/"+this.month+"/"+flag[i]+"');return false;\">" + flag[i] + "";

}

}

});

$("idcalendarpre").onclick = function(){ cale.premonth(); }

$("idcalendarnext").onclick = function(){ cale.nextmonth(); }

$("idcalendarpreyear").onclick = function(){ cale.preyear(); }

$("idcalendarnextyear").onclick = function(){ cale.nextyear(); }

$("idcalendarnow").onclick = function(){ cale.nowmonth(); }

完整实例下载

转载请注明出处:http://www.cnblogs.com/cloudgamer/

如有任何建议或疑问,欢迎留言讨论。

如果觉得文章不错的话,欢迎点一下右下角的推荐。

程序中包含的js工具库cjl.0.1.min.js,原文在这里

标签: javascript, date, 日历, blog

绿色通道:好文要顶关注我收藏该文与我联系

posted @ 2008-08-23 00:25 cloudgamer 阅读(30189) 评论(75)编辑 收藏

发表评论

2273673

回复 引用 查看

#1楼 2008-08-23 02:31 clefoo

兼容不

回复 引用 查看

#2楼 2008-08-23 05:24 飞天小肥猪(膘叔)

能弹出不?

回复 引用 查看

#3楼[楼主] 2008-08-23 08:20 cloudgamer

@clefoo

兼容的

@飞天小肥猪(膘叔)

弹出的那种网上有很多了我做的不是那种

回复 引用 查看

#4楼 2008-08-27 15:46 陛下

兄弟看上去精于js啊,多指点!

回复 引用 查看

#5楼[楼主] 2008-08-27 17:26 cloudgamer

@陛下

共同学习

回复 引用

#6楼 2008-09-01 10:25 joyce004[未注册用户]

var $ = function (id) {

return "string" == typeof id ? document.getelementbyid(id) : id;

};

var class = {

create: function() {

return function() {

this.initialize.apply(this, arguments);

}

}

}

object.extend = function(destination, source) {

for (var property in source) {

destination[property] = source[property];

}

return destination;

}

请问下这几段代码是什么意思,看的懂,不过不是很明白这样做的好处,可以解释一下吗?

回复 引用 查看

#7楼[楼主] 2008-09-01 13:55 cloudgamer

@joyce004

你可以看看initialize和setoptions的使用

回复 引用 查看

#8楼 2008-09-02 11:23 杨阳

代码质量相当搞

回复 引用 查看

#9楼[楼主] 2008-09-02 20:10 cloudgamer

@杨阳

谢谢支持

回复 引用

#10楼 2008-10-18 21:28 xukongqiang[未注册用户]

太强了,很精炼

回复 引用 查看

#11楼[楼主] 2008-10-19 13:14 cloudgamer

@xukongqiang

谢谢

回复 引用 查看

#12楼 2008-10-23 14:03 selfocus

兄台确实精于js的高手,多交流哦!

回复 引用 查看

#13楼[楼主] 2008-10-23 19:57 cloudgamer

@selfocus

呵呵

多多交流

回复 引用

#14楼 2008-11-06 10:49 ""kkking[未注册用户]

选 择 时 最 好 屏 幕 别 闪 ,还 有 有 无 带 农 历 的 ?谢 谢

回复 引用 查看

#15楼[楼主] 2008-11-06 16:11 cloudgamer

@""kkking

屏幕闪是什么意思?我这里好像没有闪哦

农历有空的话试试加进去

回复 引用

#16楼 2008-11-10 09:42 112233[未注册用户]

为什么10号,15号,20号是红字的

回复 引用 查看

#17楼[楼主] 2008-11-10 10:13 cloudgamer

@112233

对有数据的日期的也在这里设置,例如实例中是有一个当前月份的有数据的日期列表,然后根据这个列表对相应的日期进行设置:

var flag = [10,15,20];

for(var i = 0, len = flag.length; i

回复 引用

#18楼 2009-01-15 22:32 liminz[未注册用户]

你好,我想请教有个现有的日历里的默认字体的颜色无法更改,请求楼主的帮忙.

我就发给你的邮箱吧,这里也不能挂附件.

回复 引用

#19楼 2009-02-17 14:29 mymickey[未注册用户]

想问问 getutcfullyear 和getfullyear的区别 我试了试都一样的呢

回复 引用 查看

#20楼[楼主] 2009-02-18 09:30 cloudgamer

@mymickey

utc就是协调世界时

具体去baidu一下吧

我也不太懂

回复 引用

#21楼 2009-02-23 04:16 soso0704

你好,我很想一个html源码的日历放在我网页上,但我找了很久都是不行的,自己又不会弄,你可以发这个给我吗?邮箱:soso840704@163.com。

回复 引用 查看

#22楼[楼主] 2009-02-23 08:21 cloudgamer

@soso0704

不是有完整实例下载了吗

http://files.cnblogs.com/cloudgamer/blogcalendar.rar

回复 引用

#23楼 2009-02-23 13:23 我爱你

lz怎样把10号,15号,20号的特殊处理改为全部日期,并且日期添加处理是链接matter.html

回复 引用 查看

#24楼[楼主] 2009-02-23 15:49 cloudgamer

@我爱你

你可以参考测试代码中onfinish是怎么写的

然后修改一下就可以了

回复 引用

#25楼 2009-02-23 19:19 我爱你

难道要把10.15.20改为1.2.3.....31吗?

回复 引用 查看

#26楼[楼主] 2009-02-24 08:25 cloudgamer

@我爱你

那个for循环改成1到31不就行了嘛

回复 引用

#27楼 2009-02-26 14:20 deandean[未注册用户]

回楼主,我把for循环改成1到31后发现一个问题,如果当前月有31天,那么可以选择下一月或者下一年,如果当前月只有28天,比如说2月,那么就无法选择下一月或者下一年了。

回复 引用 查看

#28楼[楼主] 2009-02-26 14:25 cloudgamer

@deandean

你可以把monthday 作为onfinish的参数传递过去

就可以在函数中获取有多少天了

回复 引用

#29楼 2009-03-17 17:12 新猪猪[未注册用户]

呵呵,最好是那种,绑定到一个文本框onfocus就直接出来,比如my97datepicker那种,当然最好是带上时间的选择,比如后台要做统计,需要2个日期选择(当然包含时间最好),我也正在写,日期写完了,再加时间,当时相信楼主的js一定比我的好,呵呵。。。希望可以向你多学习学习。。。

回复 引用 查看

#30楼[楼主] 2009-03-17 17:18 cloudgamer

@新猪猪

其实原理都是那样的了

而且我自己也是用my97datepicker就不需要自己写一个了

相信你写的也不错,加油

回复 引用

#31楼 2009-03-25 13:39 swd[未注册用户]

判断这个月份有几天在哪定义的

回复 引用 查看

#32楼[楼主] 2009-03-25 13:51 cloudgamer

@swd

上面不是说了嚒

new date(this.year, this.month, 0).getdate()

回复 引用

#33楼 2009-04-14 17:12 sdj[未注册用户]

你好!看了你的许多代码,都有一个共同的不明白之处就是:

extend(this.options, options || {});

extend方法的第二个参数是什么意思呢

回复 引用 查看

#34楼[楼主] 2009-04-14 17:28 cloudgamer

@sdj

options 是函数的参数

回复 引用

#35楼 2009-04-15 09:35 sdj[未注册用户]

楼主好啊,

extend(this.options, options || {});

extend方法的第二个参数是什么意思呢,

我指的是 "options || {}",这个得到的是什么结果,谢谢楼主

回复 引用 查看

#36楼[楼主] 2009-04-15 10:20 cloudgamer

@sdj

如果options 这个参数有的话就用options 如果没有的话就用{}

||的这个用法可以参考这里

https://developer.mozilla.org/en/core_javascript_1.5_guide/operators/logical_operators

回复 引用 查看

#37楼 2009-06-26 14:16 louis.lu.sz

讲解的非常非常的详细。

赞!

回复 引用 查看

#38楼 2009-08-25 16:23 wtcsy

对比了一下cloudgamer和果果的日历,

还是喜欢cloudgamer的写法,

虽然果果的那个上面有很多值得学习的地方...........

回复 引用 查看

#39楼[楼主] 2009-08-25 17:52 cloudgamer

@wtcsy

@louis.lu.sz

谢谢支持

回复 引用

#40楼 2009-08-31 18:40 jtootl[未注册用户]

博主真强!顶你!楼主是巨人,我用了博主的代码,所以我是站在巨人的肩膀上了,哈哈。

不过要是能多提供几种样式就更好了,呵呵。

对了 日历的大小能变动吗?

回复 引用 查看

#41楼[楼主] 2009-08-31 22:35 cloudgamer

@jtootl

样式其实都可以自己设的

我关键还是在js的部分

回复 引用

#42楼 2009-09-03 14:17 jtootl[未注册用户]

再请问下博主,我能把月份做成链接吗?

>

“9月”那里,

我想的是如果想看9月的博文,就点“9月”的链接。

回复 引用 查看

#43楼[楼主] 2009-09-03 15:32 cloudgamer

@jtootl

可以啊

$("idcalendaryear").innerhtml = this.year; $("idcalendarmonth").innerhtml = this.month;

这部分拟改成一个连接就行啦

回复 引用

#44楼 2009-10-08 11:18 goodluckxw[未注册用户]

您好 请问一下这个控件 点击日期为什么点不了呢 如果想点击某个日期 焦点还要落在点击的日期上 怎么处理?

回复 引用 查看

#45楼[楼主] 2009-10-08 16:29 cloudgamer

@goodluckxw

你可以参考

for(var i = 1, len = this.days.length; i

回复 引用

#46楼 2009-10-28 16:44 lengwei[未注册用户]

var class = {

create: function() {

return function() {

this.initialize.apply(this, arguments);

}

}

}

var extend = function(destination, source) {

for (var property in source) {

destination[property] = source[property];

}

return destination;

}

楼主 这两段不怎么理解啊!

回复 引用 查看

#47楼[楼主] 2009-10-28 17:03 cloudgamer

@lengwei

可以看看apply的用法

后面那个是扩展对象

回复 引用 查看

#48楼 2009-10-30 10:37 流风--回雪

var class = {

create: function() {

return function() {

this.initialize.apply(this, arguments);

}

}

}

var extend = function(destination, source) {

for (var property in source) {

destination[property] = source[property];

}

return destination;

}

楼主 你这段内容是不是借鉴prototype.js的源码?好熟悉啊。。呵呵

回复 引用 查看

#49楼[楼主] 2009-10-30 10:49 cloudgamer

@流风--回雪

是啊,就是抄它的

呵呵

回复 引用 查看

#50楼 2009-11-02 15:18 chinarenkai

我比较认真的看完了。也做了一个小demo,跟数据库绑定,设计的不错,注释非常perfect,佩服!哈哈

回复 引用

#51楼 2009-11-10 14:35 gorden[未注册用户]

能支持中国日历就完美了

回复 引用 查看

#52楼[楼主] 2009-11-10 17:17 cloudgamer

@gorden

下次修改的话可以考虑

@chinarenkai

谢谢支持

回复 引用

#53楼 2009-11-11 18:33 mindycooky[未注册用户]

cloudgamer:

我想问一下啊,我js不好的:(

如何根据已有日期初始化日历呢?比如我点上个月,带日期参数重新调入页面,这个时候,我在哪里设置日历的年、月,并根据这个年月重新画呢?

回复 引用 查看

#54楼[楼主] 2009-11-11 20:31 cloudgamer

@mindycooky

设置这两个属性

year:要显示的年份

month:要显示的月份

回复 引用

#55楼 2009-11-12 20:25 mindycooky[未注册用户]

引用cloudgamer:

@mindycooky

设置这两个属性

year:要显示的年份

month:要显示的月份

********************************************

非常谢谢博主及时的回复!

你的代码写的挺好的,我做的项目中引用了,祝你工作顺利!

回复 引用 查看

#56楼[楼主] 2009-11-13 08:21 cloudgamer

@mindycooky

谢谢支持

回复 引用 查看

#57楼 2009-12-02 15:41 流风--回雪

楼主我已经在项目中采用你的日历,写的真的很好,尤其是提供了一些接口,扩展性相当的棒!

回复 引用

#58楼 2010-10-27 10:17 vai[未注册用户]

var $ = function (id) {

return "string" == typeof id ? document.getelementbyid(id) : id;

};

var class = {

create: function() {

return function() {

this.initialize.apply(this, arguments);

//将this对象和arguments参数放入initialize中

//return时候返回该对象

/*

这里坐下说明,例如 objecta有abc三个元素

当objecta.a去apply或者call objectb的时候假设里面包含d

组成是 就成了objecta有abcd并执行d

*/

}

}

}

object.extend = function(destination, source) {

for (var property in source) {

//将source对象覆盖到destination,然后return

destination[property] = source[property];

}

return destination;

}

lengwei,不知道能不能帮到你,虽然才开始看lz的博客,而且晚了一年

回复 引用 查看

#59楼 2010-12-12 15:16 penguin

哥们,厉害

回复 引用 查看

#60楼 2011-03-24 15:43 angxuan

实例中是固定了这个日期列表,实际应用中可以根据年份月份获取对应的日期列表,个人推荐用年份月份通过ajax获取。

==

此处的flag貌似无法通过ajax获取值,ajax内部flag有值,到外面for循环就不存在了,放在ajax内部循环更行不通.一时没查出什么原因。lz可试试,也可顺便给个回复

回复 引用 查看

#61楼[楼主] 2011-03-24 16:41 cloudgamer

@penguin

谢谢支持

回复 引用 查看

#62楼[楼主] 2011-03-24 16:47 cloudgamer

@angxuan

我就是放在ajax里面设置的 没发现问题

回复 引用 查看

#63楼 2011-03-24 17:00 angxuan

嗯,重新改了下,将构造new calendar及相关click方法置于ajax的success方法里搞定

回复 引用 查看

#64楼 2011-03-24 17:43 angxuan

可贴你ajax设置部分代码一看..

回复 引用

#65楼 2011-03-24 20:25 lollol[未注册用户]

错误: 'this.days' 为空或不是对象

回复 引用 查看

#66楼[楼主] 2011-03-24 23:07 cloudgamer

@lollol

这里没问题

回复 引用 查看

#67楼 2011-04-27 16:59 tech

预览了一下全部的js特效文章中的demo,很好,很强大

有时间来慢慢看

回复 引用

#68楼 2011-07-28 15:45 lolol[未注册用户]

求教,怎么实现一个输入日期的下拉菜单,第一个选择年份,第二个月份,关键是第三个,能自动判断某月的天数,谢谢啦

回复 引用 查看

#69楼[楼主] 2011-07-29 08:54 cloudgamer

@tech

谢谢支持

回复 引用 查看

#70楼[楼主] 2011-07-29 08:54 cloudgamer

@lolol

看这个

http://www.cnblogs.com/cloudgamer/archive/2008/10/28/1040403.html

回复 引用

#71楼 2011-07-29 15:31 lolol[未注册用户]

@cloudgamer

初学javascritp,谢谢指导。

回复 引用 查看

#72楼 2011-07-30 21:17 默^_^默

请问怎么得到星期几?

回复 引用 查看

#73楼[楼主] 2011-08-03 17:01 cloudgamer

@默^_^默

getday

回复 引用 查看

#74楼 2011-08-27 11:53 落碧

好东西感谢楼主分享...hoho

回复 引用 查看

#75楼 2011-12-19 14:40 飞船

有个建议,每次重绘日历控件都要重新creat这么多dom,是不是可以修改下,dom建立完成后,每次重绘改为每次只要填日期数据。要知道浏览器每次创建dom是很耗时的。楼主的控件不错,借鉴了。

刷新评论列表刷新页面返回页首

发表评论

昵称: [登录]

[注册]

主页:

邮箱:(仅博主可见)

验证码:看不清。
       换一个

评论内容:

记住我的昵称和主页

-->

登录注册

[使用ctrl+enter键快速提交评论]

0

1274459

oiqaevzdhxg=

首页博问闪存新闻园子招聘知识库

最新it新闻:

·windows 7官方rss动态主题:《昆虫》

·捡到iphone 4s玩自拍 icloud同步酿悲剧

·铁道部购票网站存泄密危险 cdn服务商技术短板是主因

·利用 mimo magictouch 打造另类的平板电脑

·但愿大嘴巴的消息再次失准

» 更多新闻...

最新知识库文章:

·设计师的品牌意识

·如何成为“10倍效率”开发者

·快速排序(quicksort)的javascript实现

·wcf服务端运行时架构体系详解[续篇]

·wcf服务端运行时架构体系详解[下篇]

» 更多知识库文章...

china-pub 2011秋季教材巡展

china-pub 计算机绝版图书按需印刷服务


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值