推荐兼容 IE、 FireFox 的 javascript 日历控件

推荐兼容 IE、 FireFox 的 javascript 日历控件
原创作者:寒羽枫(cityhunter172)

一、简介与声明

此日历控件是 CSDN 网友 KimSoft 的作品:http://blog.csdn.net/kimsoft/archive/2006/05/24/753225.aspx。界面清爽,纯脚本运行,实现了日期的回显功能,最重要的是兼容 FireFox 。
为了适应更多需求,我针对该控件做了以下修改:
1、返回日期的输出格式,我改成了由用户以参数形式指定 Style
2、关于 IE 中 <select> 下拉框的处理,不调用隐藏,而是用<iframe>直接覆盖
3、不使用 //this.panel.style.visibility = "hidden"; 因为它在 FireFox 中会掩盖之前出现过地方下面的链接文字,而是改用 this.panel.style.display = "none";
4、新增失去焦点后,整个 WebCalendar 即隐藏

此控件版权归属于
KimSoft ,大家在使用过程中请勿删除文中的版权声明,谢谢!再次感谢 KimSoft的开源。

[原作者 kimsoft 于2006-11-28 22:00:00 发表:此代码可以任意修改、欢迎传播]
2006 - 12- 03 ,我针对目前出现的BUG 做了以下修正:
1、把原控件中的 <form> 变成<div>,解决不能在页面的 form 标签中引用该脚本的 BUG
2、新增突出已选择的日期的背景色
3、不需要每次使用都初始化实例,整张页面共用一个实例,加快显示速度

二、修改后的代码

以下是 WebCalendar.js 修改后的源码

<!--
var cal;
var isFocus = false ; // 是否为焦点
//
以上为寒羽枫2006-06-25添加的变量

// 选择日期→由寒羽枫2006-06-25添加
function SelectDate(obj,strFormat)
... {
vardate=newDate();
varby=date.getFullYear()-50;//最小值→50年前
varey=date.getFullYear()+50;//最大值→50年后
//cal=newCalendar(by,ey,1,strFormat);//初始化英文版,0 为中文版
cal=(cal==null)?newCalendar(by,ey,1):cal;//不用每次都初始化2006-12-03修正
cal.dateFormatStyle=strFormat;
cal.show(obj);
}

/**/ /**/ /**/ /**
*返回日期
*@paramdthedelimiter
*@parampthepatternofyourdate
2006-06-25由寒羽枫修改为根据用户指定的style来确定;
*/

// String.prototype.toDate=function(x,p){
String.prototype.toDate = function (style) ... {
/**//**//**//*
if(x==null)x="-";
if(p==null)p="ymd";
vara=this.split(x);
vary=parseInt(a[p.indexOf("y")]);
//remembertochangethisnextcentury;)
if(y.toString().length<=2)y+=2000;
if(isNaN(y))y=newDate().getFullYear();
varm=parseInt(a[p.indexOf("m")])-1;
vard=parseInt(a[p.indexOf("d")]);
if(isNaN(d))d=1;
returnnewDate(y,m,d);
*/

vary=this.substring(style.indexOf('y'),style.lastIndexOf('y')+1);//
varm=this.substring(style.indexOf('M'),style.lastIndexOf('M')+1);//
vard=this.substring(style.indexOf('d'),style.lastIndexOf('d')+1);//
if(isNaN(y))y=newDate().getFullYear();
if(isNaN(m))m=newDate().getMonth();
if(isNaN(d))d=newDate().getDate();
vardt;
eval(
"dt=newDate('"+y+"','"+(m-1)+"','"+d+"')");
returndt;
}


/**/ /**/ /**/ /**
*格式化日期
*@paramdthedelimiter
*@parampthepatternofyourdate
*@authormeizz
*/

Date.prototype.format
= function (style) ... {
varo=...{
"M+":this.getMonth()+1,//month
"d+":this.getDate(),//day
"h+":this.getHours(),//hour
"m+":this.getMinutes(),//minute
"s+":this.getSeconds(),//second
"w+":"天一二三四五六".charAt(this.getDay()),//week
"q+":Math.floor((this.getMonth()+3)/3),//quarter
"S":this.getMilliseconds()//millisecond
}

if(/(y+)/.test(style))...{
style
=style.replace(RegExp.$1,
(
this.getFullYear()+"").substr(4-RegExp.$1.length));
}

for(varkino)...{
if(newRegExp("("+k+")").test(style))...{
style
=style.replace(RegExp.$1,
RegExp.$
1.length==1?o[k]:
(
"00"+o[k]).substr((""+o[k]).length));
}

}

returnstyle;
}
;

/**/ /**/ /**/ /**
*日历类
*@parambeginYear1990
*@paramendYear2010
*@paramlang0(中文)|1(英语)可自由扩充
*@paramdateFormatStyle"yyyy-MM-dd";
*@version2006-04-01
*@authorKimSoft(jinqinghua[at]gmail.com)
*@update
*/

function Calendar(beginYear,endYear,lang,dateFormatStyle) ... {
this.beginYear=1990;
this.endYear=2010;
this.lang=0;//0(中文)|1(英文)
this.dateFormatStyle="yyyy-MM-dd";

if(beginYear!=null&&endYear!=null)...{
this.beginYear=beginYear;
this.endYear=endYear;
}

if(lang!=null)...{
this.lang=lang
}


if(dateFormatStyle!=null)...{
this.dateFormatStyle=dateFormatStyle
}


this.dateControl=null;
this.panel=this.getElementById("calendarPanel");
this.container=this.getElementById("ContainerPanel");
this.form=null;

this.date=newDate();
this.year=this.date.getFullYear();
this.month=this.date.getMonth();


this.colors=...{
"cur_word":"#FFFFFF",//当日日期文字颜色
"cur_bg":"#00FF00",//当日日期单元格背影色
"sel_bg":"#FFCCCC",//已被选择的日期单元格背影色2006-12-03寒羽枫添加
"sun_word":"#FF0000",//星期天文字颜色
"sat_word":"#0000FF",//星期六文字颜色
"td_word_light":"#333333",//单元格文字颜色
"td_word_dark":"#CCCCCC",//单元格文字暗色
"td_bg_out":"#EFEFEF",//单元格背影色
"td_bg_over":"#FFCC00",//单元格背影色
"tr_word":"#FFFFFF",//日历头文字颜色
"tr_bg":"#666666",//日历头背影色
"input_border":"#CCCCCC",//input控件的边框颜色
"input_bg":"#EFEFEF"//input控件的背影色
}


this.draw();
this.bindYear();
this.bindMonth();
this.changeSelect();
this.bindData();
}


/**/ /**/ /**/ /**
*日历类属性(语言包,可自由扩展)
*/

Calendar.language
= ... {
"year":[[""],[""]],
"months":[["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
[
"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"]
],
"weeks":[["","","","","","",""],
[
"SUN","MON","TUR","WED","THU","FRI","SAT"]
],
"clear":[["清空"],["CLS"]],
"today":[["今天"],["TODAY"]],
"close":[["关闭"],["CLOSE"]]
}


Calendar.prototype.draw
= function () ... {
calendar
=this;

varmvAry=[];
//mvAry[mvAry.length]='<formname="calendarForm"style="margin:0px;">';//因<form>不能嵌套,2006-12-01由寒羽枫改用Div
mvAry[mvAry.length]='<divname="calendarForm"style="margin:0px;">';
mvAry[mvAry.length]
='<tablewidth="100%"border="0"cellpadding="0"cellspacing="1">';
mvAry[mvAry.length]
='<tr>';
mvAry[mvAry.length]
='<thalign="left"width="1%"><inputstyle="border:1pxsolid'+calendar.colors["input_border"]+';background-color:'+calendar.colors["input_bg"]+';width:16px;height:20px;"name="prevMonth"type="button"id="prevMonth"value="&lt;"/></th>';
mvAry[mvAry.length]
='<thalign="center"width="98%"nowrap="nowrap"><selectname="calendarYear"id="calendarYear"style="font-size:12px;"></select><selectname="calendarMonth"id="calendarMonth"style="font-size:12px;"></select></th>';
mvAry[mvAry.length]
='<thalign="right"width="1%"><inputstyle="border:1pxsolid'+calendar.colors["input_border"]+';background-color:'+calendar.colors["input_bg"]+';width:16px;height:20px;"name="nextMonth"type="button"id="nextMonth"value="&gt;"/></th>';
mvAry[mvAry.length]
='</tr>';
mvAry[mvAry.length]
='</table>';
mvAry[mvAry.length]
='<tableid="calendarTable"width="100%"style="border:0pxsolid#CCCCCC;background-color:#FFFFFF"border="0"cellpadding="3"cellspacing="1">';
mvAry[mvAry.length]
='<tr>';
for(vari=0;i<7;i++)...{
mvAry[mvAry.length]
='<thstyle="font-weight:normal;background-color:'+calendar.colors["tr_bg"]+';color:'+calendar.colors["tr_word"]+';">'+Calendar.language["weeks"][this.lang][i]+'</th>';
}

mvAry[mvAry.length]
='</tr>';
for(vari=0;i<6;i++)...{
mvAry[mvAry.length]
='<tralign="center">';
for(varj=0;j<7;j++)...{
if(j==0)...{
mvAry[mvAry.length]
='<tdstyle="cursor:default;color:'+calendar.colors["sun_word"]+';"></td>';
}
elseif(j==6)...{
mvAry[mvAry.length]
='<tdstyle="cursor:default;color:'+calendar.colors["sat_word"]+';"></td>';
}
else...{
mvAry[mvAry.length]
='<tdstyle="cursor:default;"></td>';
}

}

mvAry[mvAry.length]
='</tr>';
}

mvAry[mvAry.length]
='<trstyle="background-color:'+calendar.colors["input_bg"]+';">';
mvAry[mvAry.length]
='<thcolspan="2"><inputname="calendarClear"type="button"id="calendarClear"value="'+Calendar.language["clear"][this.lang]+'"style="border:1pxsolid'+calendar.colors["input_border"]+';background-color:'+calendar.colors["input_bg"]+';width:100%;height:20px;font-size:12px;"/></th>';
mvAry[mvAry.length]
='<thcolspan="3"><inputname="calendarToday"type="button"id="calendarToday"value="'+Calendar.language["today"][this.lang]+'"style="border:1pxsolid'+calendar.colors["input_border"]+';background-color:'+calendar.colors["input_bg"]+';width:100%;height:20px;font-size:12px;"/></th>';
mvAry[mvAry.length]
='<thcolspan="2"><inputname="calendarClose"type="button"id="calendarClose"value="'+Calendar.language["close"][this.lang]+'"style="border:1pxsolid'+calendar.colors["input_border"]+';background-color:'+calendar.colors["input_bg"]+';width:100%;height:20px;font-size:12px;"/></th>';
mvAry[mvAry.length]
='</tr>';
mvAry[mvAry.length]
='</table>';
//mvAry[mvAry.length]='</from>';
mvAry[mvAry.length]='</div>';
this.panel.innerHTML=mvAry.join("");

/**//********以下代码由寒羽枫2006-12-01添加**********/
varobj=this.getElementById("prevMonth");
obj.onclick
=function()...{calendar.goPrevMonth(calendar);}
obj.onblur
=function()...{calendar.onblur();}
this.prevMonth=obj;

obj
=this.getElementById("nextMonth");
obj.onclick
=function()...{calendar.goNextMonth(calendar);}
obj.onblur
=function()...{calendar.onblur();}
this.nextMonth=obj;



obj
=this.getElementById("calendarClear");
obj.onclick
=function()...{calendar.dateControl.value="";calendar.hide();}
this.calendarClear=obj;

obj
=this.getElementById("calendarClose");
obj.onclick
=function()...{calendar.hide();}
this.calendarClose=obj;

obj
=this.getElementById("calendarYear");
obj.onchange
=function()...{calendar.update(calendar);}
obj.onblur
=function()...{calendar.onblur();}
this.calendarYear=obj;

obj
=this.getElementById("calendarMonth");
with(obj)
...{
onchange
=function()...{calendar.update(calendar);}
onblur
=function()...{calendar.onblur();}
}
this.calendarMonth=obj;

obj
=this.getElementById("calendarToday");
obj.onclick
=function()...{
vartoday=newDate();
calendar.date
=today;
calendar.year
=today.getFullYear();
calendar.month
=today.getMonth();
calendar.changeSelect();
calendar.bindData();
calendar.dateControl.value
=today.format(calendar.dateFormatStyle);
calendar.hide();
}

this.calendarToday=obj;
/**//********以上代码由寒羽枫2006-12-01添加**********/

/**//*
//this.form=document.forms["calendarForm"];
this.form.prevMonth.οnclick=function(){calendar.goPrevMonth(this);}
this.form.nextMonth.οnclick=function(){calendar.goNextMonth(this);}

this.form.prevMonth.οnblur=function(){calendar.onblur();}
this.form.nextMonth.οnblur=function(){calendar.onblur();}

this.form.calendarClear.οnclick=function(){calendar.dateControl.value="";calendar.hide();}
this.form.calendarClose.οnclick=function(){calendar.hide();}
this.form.calendarYear.οnchange=function(){calendar.update(this);}
this.form.calendarMonth.οnchange=function(){calendar.update(this);}

this.form.calendarYear.οnblur=function(){calendar.onblur();}
this.form.calendarMonth.οnblur=function(){calendar.onblur();}

this.form.calendarToday.οnclick=function(){
vartoday=newDate();
calendar.date=today;
calendar.year=today.getFullYear();
calendar.month=today.getMonth();
calendar.changeSelect();
calendar.bindData();
calendar.dateControl.value=today.format(calendar.dateFormatStyle);
calendar.hide();
}
*/

}


// 年份下拉框绑定数据
Calendar.prototype.bindYear = function () ... {
//varcy=this.form.calendarYear;
varcy=this.calendarYear;//2006-12-01由寒羽枫修改
cy.length=0;
for(vari=this.beginYear;i<=this.endYear;i++)...{
cy.options[cy.length]
=newOption(i+Calendar.language["year"][this.lang],i);
}

}


// 月份下拉框绑定数据
Calendar.prototype.bindMonth = function () ... {
//varcm=this.form.calendarMonth;
varcm=this.calendarMonth;//2006-12-01由寒羽枫修改
cm.length=0;
for(vari=0;i<12;i++)...{
cm.options[cm.length]
=newOption(Calendar.language["months"][this.lang][i],i);
}

}


// 向前一月
Calendar.prototype.goPrevMonth = function (e) ... {
if(this.year==this.beginYear&&this.month==0)...{return;}
this.month--;
if(this.month==-1)...{
this.year--;
this.month=11;
}

this.date=newDate(this.year,this.month,1);
this.changeSelect();
this.bindData();
}


// 向后一月
Calendar.prototype.goNextMonth = function (e) ... {
if(this.year==this.endYear&&this.month==11)...{return;}
this.month++;
if(this.month==12)...{
this.year++;
this.month=0;
}

this.date=newDate(this.year,this.month,1);
this.changeSelect();
this.bindData();
}


// 改变SELECT选中状态
Calendar.prototype.changeSelect = function () ... {
//varcy=this.form.calendarYear;
//varcm=this.form.calendarMonth;
varcy=this.calendarYear;//2006-12-01由寒羽枫修改
varcm=this.calendarMonth;
for(vari=0;i<cy.length;i++)...{
if(cy.options[i].value==this.date.getFullYear())...{
cy[i].selected
=true;
break;
}

}

for(vari=0;i<cm.length;i++)...{
if(cm.options[i].value==this.date.getMonth())...{
cm[i].selected
=true;
break;
}

}

}


// 更新年、月
Calendar.prototype.update = function (e) ... {
//this.year=e.form.calendarYear.options[e.form.calendarYear.selectedIndex].value;
//this.month=e.form.calendarMonth.options[e.form.calendarMonth.selectedIndex].value;
this.year=e.calendarYear.options[e.calendarYear.selectedIndex].value;//2006-12-01由寒羽枫修改
this.month=e.calendarMonth.options[e.calendarMonth.selectedIndex].value;
this.date=newDate(this.year,this.month,1);
this.changeSelect();
this.bindData();
}


// 绑定数据到月视图
Calendar.prototype.bindData = function () ... {
varcalendar=this;
vardateArray=this.getMonthViewArray(this.date.getYear(),this.date.getMonth());
vartds=this.getElementById("calendarTable").getElementsByTagName("td");
for(vari=0;i<tds.length;i++)...{
//tds[i].style.color=calendar.colors["td_word_light"];
tds[i].style.backgroundColor=calendar.colors["td_bg_out"];
tds[i].onclick
=function()...{return;}
tds[i].onmouseover
=function()...{return;}
tds[i].onmouseout
=function()...{return;}
if(i>dateArray.length-1)break;
tds[i].innerHTML
=dateArray[i];
if(dateArray[i]!="&nbsp;")...{
tds[i].onclick
=function()...{
if(calendar.dateControl!=null)...{
calendar.dateControl.value
=newDate(calendar.date.getFullYear(),
calendar.date.getMonth(),
this.innerHTML).format(calendar.dateFormatStyle);
}

calendar.hide();
}

tds[i].onmouseover
=function()...{
this.style.backgroundColor=calendar.colors["td_bg_over"];
}

tds[i].onmouseout
=function()...{
this.style.backgroundColor=calendar.colors["td_bg_out"];
}

if(newDate().format(calendar.dateFormatStyle)==
newDate(calendar.date.getFullYear(),
calendar.date.getMonth(),
dateArray[i]).format(calendar.dateFormatStyle))
...{
//tds[i].style.color=calendar.colors["cur_word"];
tds[i].style.backgroundColor=calendar.colors["cur_bg"];
tds[i].onmouseover
=function()...{
this.style.backgroundColor=calendar.colors["td_bg_over"];
}

tds[i].onmouseout
=function()...{
this.style.backgroundColor=calendar.colors["cur_bg"];
}

//continue;//若不想当天单元格的背景被下面的覆盖,请取消注释→2006-12-03寒羽枫添加
}
//endif

//设置已被选择的日期单元格背影色2006-12-03寒羽枫添加
if(calendar.dateControl!=null&&calendar.dateControl.value==newDate(calendar.date.getFullYear(),
calendar.date.getMonth(),
dateArray[i]).format(calendar.dateFormatStyle))
...{
tds[i].style.backgroundColor
=calendar.colors["sel_bg"];
tds[i].onmouseover
=function()...{
this.style.backgroundColor=calendar.colors["td_bg_over"];
}

tds[i].onmouseout
=function()...{
this.style.backgroundColor=calendar.colors["sel_bg"];
}

}

}

}

}


// 根据年、月得到月视图数据(数组形式)
Calendar.prototype.getMonthViewArray = function (y,m) ... {
varmvArray=[];
vardayOfFirstDay=newDate(y,m,1).getDay();
vardaysOfMonth=newDate(y,m+1,0).getDate();
for(vari=0;i<42;i++)...{
mvArray[i]
="&nbsp;";
}

for(vari=0;i<daysOfMonth;i++)...{
mvArray[i
+dayOfFirstDay]=i+1;
}

returnmvArray;
}


// 扩展document.getElementById(id)多浏览器兼容性frommeizztreesource
Calendar.prototype.getElementById = function (id) ... {
if(typeof(id)!="string"||id=="")returnnull;
if(document.getElementById)returndocument.getElementById(id);
if(document.all)returndocument.all(id);
try...{returneval(id);}catch(e)...{returnnull;}
}


// 扩展object.getElementsByTagName(tagName)
Calendar.prototype.getElementsByTagName = function (object,tagName) ... {
if(document.getElementsByTagName)returndocument.getElementsByTagName(tagName);
if(document.all)returndocument.all.tags(tagName);
}


// 取得HTML控件绝对位置
Calendar.prototype.getAbsPoint = function (e) ... {
varx=e.offsetLeft;
vary=e.offsetTop;
while(e=e.offsetParent)...{
x
+=e.offsetLeft;
y
+=e.offsetTop;
}

return...{"x":x,"y":y};
}


// 显示日历
Calendar.prototype.show = function (dateObj,popControl) ... {
if(dateObj==null)...{
thrownewError("arguments[0]isnecessary")
}

this.dateControl=dateObj;

//if(dateObj.value.length>0){
//this.date=newDate(dateObj.value.toDate());
//this.date=newDate(dateObj.value.toDate(this.dateFormatStyle));//由寒羽枫修改,带入用户指定的style
this.date=(dateObj.value.length>0)?newDate(dateObj.value.toDate(this.dateFormatStyle)):newDate();//2006-12-03寒羽枫添加→若为空则显示当前月份
this.year=this.date.getFullYear();
this.month=this.date.getMonth();
this.changeSelect();
this.bindData();
//}
if(popControl==null)...{
popControl
=dateObj;
}

varxy=this.getAbsPoint(popControl);
this.panel.style.left=xy.x-25+"px";
this.panel.style.top=(xy.y+dateObj.offsetHeight)+"px";

//由寒羽枫2006-06-25修改→把visibility变为display,并添加失去焦点的事件
//this.setDisplayStyle("select","hidden");
//this.panel.style.visibility="visible";
//this.container.style.visibility="visible";
this.panel.style.display="";
this.container.style.display="";

dateObj.onblur
=function()...{calendar.onblur();}
this.container.onmouseover=function()...{isFocus=true;}
this.container.onmouseout=function()...{isFocus=false;}
}


// 隐藏日历
Calendar.prototype.hide = function () ... {
//this.setDisplayStyle("select","visible");
//this.panel.style.visibility="hidden";
//this.container.style.visibility="hidden";
this.panel.style.display="none";
this.container.style.display="none";
isFocus
=false;
}


// 焦点转移时隐藏日历→由寒羽枫2006-06-25添加
Calendar.prototype.onblur = function () ... {
if(!isFocus)...{this.hide();}
}


// 以下由寒羽枫2006-06-25修改→用<iframe>遮住IE的下拉框
/**/ /**/ /**/ /*
//设置控件显示或隐藏
Calendar.prototype.setDisplayStyle=function(tagName,style){
vartags=this.getElementsByTagName(null,tagName)
for(vari=0;i<tags.length;i++){
if(tagName.toLowerCase()=="select"&&
(tags[i].name=="calendarYear"||
tags[i].name=="calendarMonth")){
continue;
}
//tags[i].style.visibility=style;
tags[i].style.display=style;
}
}
*/

// document.write('<divid="ContainerPanel"style="visibility:hidden"><divid="calendarPanel"style="position:absolute;visibility:hidden;z-index:9999;');
document.write( ' <divid="ContainerPanel"style="display:none"><divid="calendarPanel"style="position:absolute;display:none;z-index:9999; ' );
document.write(
' background-color:#FFFFFF;border:1pxsolid#CCCCCC;width:175px;font-size:12px;"></div> ' );
if (document.all)
... {
document.write(
'<iframestyle="position:absolute;z-index:2000;width:expression(this.previousSibling.offsetWidth);');
document.write(
'height:expression(this.previousSibling.offsetHeight);');
document.write(
'left:expression(this.previousSibling.offsetLeft);top:expression(this.previousSibling.offsetTop);');
document.write(
'display:expression(this.previousSibling.style.display);"scrolling="no"frameborder="no"></iframe>');
}

document.write(
' </div> ' );
// varcalendar=newCalendar();//此句被寒羽枫注释,否则IE将报错
//
调用calendar.show(dateControl,popControl);
//
-->


三、调用方法

1、引用 WebCalendar.js

< script src ="js/WebCalendar.js" type ="text/javascript" ></ script >

2、编写触发的脚本事件

this .Txt_Date.Attributes[ " onclick " ] = " SelectDate(this,'yyyy-MM-dd') " ;

< input name ="Txt_Date" type ="text" maxlength ="10" id ="Txt_Date" onclick ="SelectDate(this,'yyyy/MM/dd')" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值