网站首页 手机版
 注册 登录
您现在的位置: 畅无忧设计 >> 网页特效 >> 日期时间 >> 正文
最新文章
· Js简单获取系统日期/时间/星期
· 小巧实用的日历
· Js日期选择并自动加入输入框
· 可开始暂停停止的js计时器
· JavaScript日历生成器
· 动态显示当前时间并显示当前是上午还
· 中英文双语日期选择器
· 非常好用的JS日历控件ESONCalendar
· 简单的日期时间控件
· 简洁漂亮的JS日历控件代码
热门文章
 可开始暂停停止的js计时器
 可精确到分钟的js日期时间控件
 基于JQuery的日历控件
 JavaScript动态显示系统时间(带年
 一个可精确到时分秒的日期时间控件
 距离某年某月某日还有多少天
 日期时间控件My97 DatePicker 4.7 
 非常好用的JS日历控件ESONCalendar
 简洁漂亮的JS日历控件代码
 精确到毫秒的动态时间显示
相关文章
中英文双语日期选择器
非常好用的JS日历控件ESONCalendar
简单的日期时间控件
基于JQuery的日历控件
一款比较清爽的日历控件
日期时间控件My97 DatePicker 4.7 Releas
可自由选择时间长度的js日期时间控件
站长统计中使用的js日历控件
支持快捷键的javascript日期控件
一个可精确到时分秒的日期时间控件
可精确到分钟的js日期时间控件
兼容各种浏览器的日期控件
JCalendar 日历控件 v1.0 beta
来源:蓝色理想 更新时间:2010/8/29 23:25:24 阅读次数: 我要投稿
△运行 ☉预览 #复制 +收藏
特效代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Language" content="zh-cn" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JCalendar 日历控件 v1.0 beta</title>
<style type="text/css">
body {
 font-size:12px;
 font-family:'Lucida Grande','Lucida Sans Unicode','宋体',arial,verdana,sans-serif;
}
input,select{
 border:1px solid #369;
 font-size:12px;
 margin:0 5px;
}
input {
 width:180px;
}
fieldset {
 margin:5px;
 padding:0 12px 12px 12px;
 border:1px solid #D4D4D4;
 background-color:#F9F9F9;
}
legend {
 font-weight:bold;
}
.center {
 text-align:center;
}
.red {
 color:#F00;
}
/**********日历样式开始********************/
#calendar_container {
 width:160px;
 border:1px solid #06C;
}
#calendar {
 border-collapse:collapse;
 background-color:#FFF;
 width:160px;
 height:120px;
 margin:0px auto;
 cursor:default;
}
#calendar td {
 font-size:12px;
 text-align:center;
 vertical-align:middle;
 font-family:"宋体";
}
#calendar thead {
 background-color:#999;
 color:#FFF;
}
#calendar caption {
 background-color:#06C;
}
#calendar a{
 color:#F90;
 margin:0 5px;
 text-decoration:none;
}
#calendar #prev_month,#calendar #next_month {
 font-size:18px;
 margin:0;
}
#calendar #c_today {
 background-color:#036;
 color:#FFF;
}
#calendar .over {
 background-color:#CCC;
}
#calendar .keydate {
 color:#06F;
}
</style>
<script type="text/javascript" defer="defer">
//////////////////基本函数库/////////////////////////////
var isIE = /msie/i.test(navigator.userAgent);
var isDTD = /CSS1Compat/i.test(document.compatMode);
if(!isIE){
 window.constructor.prototype.__defineGetter__("event",function(){
  var func = arguments.callee.caller;
  while(func != null){
   var arg0 = func.arguments[0];
   if(arg0 && (arg0.constructor==Event || arg0.constructor ==MouseEvent)){
    return arg0;
   }
   func = func.caller;
  }
     return null;
 });
 Event.prototype.__defineSetter__("returnValue",function(b){
  if(!b)this.preventDefault();
  return b;
 });
 Event.prototype.__defineGetter__("srcElement",function(){
  var node=this.target;
  while(node.nodeType != 1)node=node.parentNode;
  return node;
 });
 Event.prototype.__defineGetter__("offsetX",function(){
   return this.layerX;
 });
 Event.prototype.__defineGetter__("offsetY",function(){
  return this.layerY;
 });
 HTMLElement.prototype.attachEvent = function(sType,foo){
  this.addEventListener(sType.slice(2),foo,false);
 }
 HTMLElement.prototype.detachEvent = function(sType,foo){
  this.removeEventListener(sType.slice(2),foo,false);
 }
 HTMLDocument.prototype.attachEvent = function(sType,foo){
  this.addEventListener(sType.slice(2),foo,false);
 }
 HTMLDocument.prototype.detachEvent = function(sType,foo){
  this.removeEventListener(sType.slice(2),foo,false);
 }
 HTMLElement.prototype.__defineGetter__("innerText",function(){
  return this.textContent;
 });
 HTMLElement.prototype.__defineSetter__("innerText",function(str){
  this.textContent = str;
 });
}
else document.execCommand("BackgroundImageCache",false,true);
function $(id){return (typeof id == "string" ? document.getElementById(id) : id);}
function $N(name){return document.getElementsByName(name);}
function $TN(name,root){return root ? $(root).getElementsByTagName(name) : document.getElementsByTagName(name);}
function $DC(name){return document.createElement(name);}
function exist(id){return $(id)!= null;}
function hide(){
 for(var i = 0; i < arguments.length; i++){
  if(exist(arguments[i])){
   if($(arguments[i]).style.visibility) $(arguments[i]).style.visibility = "hidden";
   else $(arguments[i]).style.display = "none";
  }
 }
}
function show(){
 for(var i = 0; i < arguments.length; i++){
  if(exist(arguments[i])){
   if($(arguments[i]).style.visibility) $(arguments[i]).style.visibility="visible";
   else $(arguments[i]).style.display = "";
  }
 }
}
</script>
<script type="text/javascript" defer="defer">
//////////////JCalendar 类////////////////////////////
/***************************
 *JCalendar日历控件
 *@author brull
 *@email [email]brull@163.com[/email]
 *@date 2007-4-16
 *@更新 2007-5-27
 *@version 1.0 beta
 ***************************/
/*
 *@param year 年份,[可选]
 *@param month 月份,[可选]
 *@param date 日期,[可选]
 *或者是以横线间隔开的日期,比如:2007-4-27
 */
 
function JCalendar (year,month,date) {
 if($("calendar"))return;//唯一实例
 var _date = null;
 if(arguments.length == 3) _date = new Date(year,month-1,date);
 else if(arguments.length == 1 && typeof arguments[0] == "string")
  _date = eval("new Date(" + arguments[0].split("-").join() + ")");
 //如果没有参数,就初始化为当天日期
 else if(arguments.length == 0) _date = new Date();
 this.year = _date.getFullYear();
 this.month = _date.getMonth() + 1;
 this.date = _date.getDate();
 this.FIRSTYEAR = 1949;
 this.LASTYEAR = 2049;
 JCalendar.cur_year = this.year;
 JCalendar.cur_month = this.month;
 JCalendar.cur_date = this.date;
 JCalendar.cur_obj_id = null;//作为输入控件时保存当前文本框的id
}
/**
 *设置日历年份下拉菜单的年份范围
 *@first 第一个年份界限
 *@last 第二个年份界限
 *两个参数顺序可以颠倒
 */
JCalendar.prototype.setYears = function(first,last){
 if(isNaN(first) || isNaN(last)) return;
 this.FIRSTYEAR = Math.min(first,last);
 this.LASTYEAR = Math.max(first,last);
}
/**
 *以HTML串返回日历控件的HTML代码
 */
JCalendar.prototype.toString = function(){
 var fday = new Date(this.year,this.month-1,1).getDay();//每月第一天的星期数
 var select_year = new Array();//年份下拉菜单
 var select_month = new Array();//月份下拉菜单
 //日历里的每个单元格的数据,预先定义一段空数组,对应日历里第一周空的位置。[注意星期天对应的数是0]
 var date = new Array(fday > 0 ? fday - 1 : 0);
 var dayNum = new Date(this.year,this.month,0).getDate();//每月的天数
 var html_str = new Array();//保存日历控件的HTML代码
 var date_index = 0;//date数组的索引
 var weekDay = ["日","一","二","三","四","五","六"];
 
 //填充年份下拉菜单
 select_year.push("<select id='select_year'  style='display:none' onblur =\"hide(this);show('title_year')\" onchange='JCalendar.update(this.value,JCalendar.cur_month)'>");
 for(var i = this.FIRSTYEAR; i <= this.LASTYEAR; i++){
  if(i == this.year)
   select_year.push("<option value='" + i + "' selected='selected'>" + i +"</option>");
  else
   select_year.push("<option value='" + i + "'>" + i +"</option>");
 }
 select_year.push("</select>");
 
 //填充月份下拉菜单
 select_month.push("<select  id='select_month' style='display:none'  onblur =\"hide(this);show('title_month')\" onchange='JCalendar.update(JCalendar.cur_year,this.value)'>");
 for(var i = 1; i <= 12; i++){
  if(i == this.month)
   select_month.push("<option value='" + i + "' selected='selected'>" + i +"月</option>");
  else
   select_month.push("<option value='" + i + "'>" + i +"月</option>");
 }
 select_month.push("</select>");
 //初始化date数组
 for(var j = 1; j <= dayNum; j++){
  date.push(j);
 }
 //开始构建日历控件的HTML代码
 html_str.push("<table id='calendar'>");
 //日历表格caption
 html_str.push("<caption>" + "<a href='#'  id='prev_month' title='上一月份' onclick=\"JCalendar.update(JCalendar.cur_year,JCalendar.cur_month-1);return false;\">«</a><a href='#' id='title_year' title='点击选择年份' onclick=\"hide(this);show('select_year');$('select_year').focus();return false\">" + this.year + "年</a>" + select_year.join("") + "<a href='#' id='title_month' title='点击选择月份' onclick=\"hide(this);show('select_month');$('select_month').focus();return false\">" + this.month + "月</a>" + select_month.join("") + "<a href='#' id='next_month' title='下一月份' onclick=\"JCalendar.update(JCalendar.cur_year,JCalendar.cur_month+1);return false;\">»</a></caption>");
 //日历表格头
 html_str.push("<thead><tr>");
 for(var i = 0; i < 7; i++){//填充日历头
  html_str.push("<td>" + weekDay[i] + "</td>");
 }
 html_str.push("</tr></thead>");
 //日历主体
 var tmp;
 html_str.push("<tbody>");
 for(var i = 0; i < 6; i++){//填充日期,6行7列
  html_str.push("<tr>");
  for(var j = 0; j < 7; j++){
   tmp = date[date_index++];
   if(!tmp) tmp = "";
   html_str.push("<td ");
   if(tmp == this.date) html_str.push("id='c_today' ");
   html_str.push("onmouseover='JCalendar.over(this)' onmouseout='JCalendar.out(this)' onclick='JCalendar.click(this)'>" + tmp + "</td>");
  }
  html_str.push("</tr>");
 }
 html_str.push("</tbody></table>");
 return html_str.join("");
}
/**
 *特别显示关键天,典型例子博客的日历
 * 实现原理,为每个关键天的表格单元添加一个class,名字为keydate,CSS样式需要自己写,比如加个背景之类的
 *@param 日期的数组,比如:[1,4,6,9]
 */
JCalendar.prototype.setKeyDate = function(){
 var dates = arguments[0];
 var tds = $TN("td",$("calendar"));
 var reg = null;
 for(var i = 0; i < dates.length; i++){
  reg = new RegExp("\\b" + dates[i] + "\\b");
  for(var j = 7; j < tds.length; j++){//忽略表格头
   if(reg.test(tds[j].innerText)){
    tds[j].className = "keydate";
    break;
   }
  }
 }
}
/**
 *可以将日历控件邦定到某个文本框,在点击文本框的时候,会在direction指定的方向弹出日历,可以多次调用来帮定多个文本框
 *@ param obj_id 需要邦定日历的文本框的id
 *@ param direction 日历出现的相对于文本框的方向 [可选] 默认为right
 */
JCalendar.prototype.bind = function(obj_id,direction){
 var obj = $(obj_id);
 var direction = direction ? direction : "right";
 if(!obj)return;
 if(!$("calendar_container")){//唯一容器
  var contain = $DC("div");
  var s = contain.style;
  s.visibility = "hidden";
  s.position = "absolute";
  s.top = "0px";//不能占据页面空间
  s.zIndex = 65530;
  contain.id = "calendar_container";
  contain.innerHTML = this.toString();
  document.body.appendChild(contain);
  if(isIE){
   var ifm = $DC("iframe");
   var s = ifm.style;
   ifm.frameBorder = 0;
   ifm.height = (contain.clientHeight - 3) + "px";
   s.visibility = "inherit";
   s.filter = "alpha(opacity=0)";
   s.position = "absolute";
   s.top = "0px";//不能占据页面空间
   s.width = $("calendar_container").offsetWidth;
   s.zIndex = -1;
   contain.insertAdjacentElement("afterBegin",ifm);
  }
 }
 //覆盖日历事件
 JCalendar.onupdate = function () {};
 JCalendar.onclick = function (year,month,date){
  $(JCalendar.cur_obj_id).value = $(JCalendar.cur_obj_id).value.replace(/^[^\s]*/i,year + '-' + month + '-' + date);
  hide("calendar_container");
 }
 //邦定事件
 document.attachEvent("onclick",function(){
  if($("calendar_container").style.visibility="visible")hide("calendar_container");
 });
 obj.attachEvent("onclick",function(e){
  var obj = e.srcElement;
  var dates =obj.value.split(/\s/)[0].split("-");//文本框日期数组,文本框内容可能有时间这样的字串,即:2007-5-26 15:39
  var left = obj.offsetLeft , top = obj.offsetTop;
  var x,y,left,top;
  var contain = $("calendar_container");
  var body = isDTD ? document.documentElement : document.body;
  left = body.scrollLeft + e.clientX - e.offsetX;
  top = body.scrollTop + e.clientY - e.offsetY;
  switch(direction){
   case "right" : x = left + obj.offsetWidth; y = top;break;
   case "bottom" : x = left; y = top + obj.offsetHeight;break;
  }
  contain.style.top = y + "px";
  contain.style.left = x + "px";
  //更新日历日期
  if(dates.length == 3 && (JCalendar.cur_year != dates[0] || JCalendar.cur_month != dates[1] || JCalendar.cur_date != dates[2]))
   JCalendar.update(dates[0],dates[1],dates[2]);//如果文本框有时间则更新时间到文本框的时间
  else if (dates.length != 3){
   var now = new Date();
   JCalendar.update(now.getFullYear(),now.getMonth() + 1,now.getDate());
  }
  if($("calendar_container").style.visibility="hidden")show("calendar_container");
  e.cancelBubble = true;
  JCalendar.cur_obj_id = obj.id;
 });
 $("calendar_container").attachEvent("onclick",function(e){e.cancelBubble = true;});
}
/*===========================静态方法=======================================*/
/**
 *更新日历内容
 */
JCalendar.update = function(_year,_month,_date){
 date = new Date(_year,_month-1,1);
 var fday = date.getDay();//每月第一天的星期数
 var year = date.getFullYear();
 var month = date.getMonth() + 1;
 var dayNum = new Date(_year,_month,0).getDate();//每月的天数
 var tds = $TN("td",$("calendar"));
 var years = $("select_year").options;
 var months = $("select_month").options;
 var _date = _date ? _date : JCalendar.cur_date;
 //更新当前年月
 JCalendar.cur_year = year;
 JCalendar.cur_month = month;
 if(_date && _date <= dayNum) JCalendar.cur_date = _date;
 else if(_date > dayNum) JCalendar.cur_date = _date - dayNum;
 $("title_year").innerText = year + "年";
 $("title_month").innerText = month + "月";
 //更新年份下拉菜单选中项
 for(var i = years.length - 1; i >= 0; i-- ){
  if(years[i].value == year){
   $("select_year").selectedIndex = i;
   break;
  }
 }
 //更新月份下拉菜单选中项
 for(var i = months.length - 1; i >= 0; i-- ){
  if(months[i].value == month){
   $("select_month").selectedIndex = i;
   break;
  }
 }
 //清空日历内容,忽略日历头,即第一行
 for(var i = 7; i < tds.length; i++) tds[i].innerText = "";
 if( $("c_today"))$("c_today").removeAttribute("id");
 for(var j = 1; j <= dayNum; j++){
  tds[6 + fday + j].innerText = j;
  if(j == JCalendar.cur_date) tds[6 + fday + j].id = "c_today";
 }
 JCalendar.onupdate(year,month,JCalendar.cur_date);
}
JCalendar.click = function(obj){
 var tmp = $("c_today");
 if(tmp && tmp == obj){
  JCalendar.onclick(JCalendar.cur_year,JCalendar.cur_month,JCalendar.cur_date);
 }
 else if(obj.innerText != ""){
  if(tmp) tmp.removeAttribute("id");
  JCalendar.cur_date = parseInt(obj.innerText);
  obj.id = "c_today";
  JCalendar.onclick(JCalendar.cur_year,JCalendar.cur_month,JCalendar.cur_date);
 }
}
JCalendar.over = function(obj){
 if(obj.innerText != "") obj.className = "over";
}
JCalendar.out = function(obj){
 if(obj.innerText != "") obj.className = "";
}
//日历更改时执行的函数,可以更改为自己需要函数,控件传递过来的参数为当前日期
JCalendar.onupdate = function(year,month,date){
 alert("日历已更改,当前日历日期:" + year + "年" + month + "月" + date + "日");
}
//点击日期时执行的函数,可以更改为自己需要函数,控件传递过来的参数为当前日期
JCalendar.onclick = function(year,month,date){
 alert( "当前触发的日期:" + year + "年" + month + "月" + date + "日");
}
</script>
<script type="text/javascript" defer="defer">
///////////////调用例子,作为输入控件////////////////
window.onload = function(){
 var j = new JCalendar();
 j.setYears(1990,2020);
 j.bind('a',"bottom");
 j.bind('b');
}
</script>
</head>
<body>
  <p class="center">
   <input name="a" type="text" id="a" title="日历在俺下面" />
   <input name="b" type="text" id="b" value="1990-1-1" title="日历在俺右边" />
  </p>
  <p class="center">
  <select>
   <option>看你能不能挡住我</option>
  </select>
  </p>
  <p class="center"> </p>
  <p class="center"> </p>
  <p class="center"> </p>
  <p class="center"> </p>
</body>
</html>
△运行 ☉预览 #复制 +收藏
特效说明:

接口说明
一、JCalendar构造函数

参数:
1、三个表示年月日的整数,比如:new JCalendar(2007-5-18)
2、一个表示年月日的字串,年月日之间以“-”隔开,比如new JCalendar("2007-5-18")
3、空。参数为空,日历初始化为当前日期。

二、实例方法
1、toString()
得到解释后的日历的HTML代码
参数:无
返回:解释后的日历的HTML代码

2、setYears(first,last)
设置日历年份下拉菜单的年份范围
参数:
1、first 第一个年份界限
2、last 第二个年份界限
两个参数顺序可以颠倒

3、bind(obj_id,direction)
将日历邦定到某个文框,当点击该文本框的时候弹出日历。
日历的当前日期为文本框里的日期,如果文本框里有日期的话。否则就是当前日期
参数:
1、obj_id:文本框的id
2、direction:控制日历显示的方向,[right|bottom]。可以为空,默认为right。
right-日历显示在文本框的右边,bottom日历显示在文本框下面。


4、setKeyDate(Date_Array)
特别显示关键天,典型例子:博客、网络日志之类的日历
实现原理,为每个关键天的表格单元添加一个class,名字为keydate,CSS样式需要自己写,比如加个背景之类的
参数:
Date_Array:日期的数组,比如:[1,4,6,9]

三、静态方法
多数静态方法是控件内部调用的,用户不应该调用。
但是有两个方法用户可以覆盖,也是日历为用户提供的两个事件:
1、JCalendar.onupdate:在日历日期更新时触发,用户需要自己写函数覆盖默认函数
2、JCalendar.onclick:在日历日期被点击时触发,用户需要自己写函数覆盖默认函数。
[注意]用作文本框输入控件时,不要覆盖。

当然,用户可以自己定义自己的日历样式,下面是样式的说明,同时也给出了本人的写的样式:
#calendar_container {/ *日历容器,是一个绝对定位的DIV,在日历作为输入控件时才有用。作为文本框输入控件时必须定义这个样式,而且一定要定义宽度 */
width:160px;
border:1px solid #06C;
}
#calendar {/*日历表格样式,对应的是一个<table>标签*/
border-collapse:collapse;
background-color:#FFF;
width:160px;
height:120px;
margin:0px auto;
cursor:default;
}
#calendar td {/*很明显,这是一个表格单元*/
text-align:center;
vertical-align:middle;
font-family:"宋体";
}
#calendar thead {/*表格头,也就是显示日一二三四五六那行*/
background-color:#999;
color:#FFF;
}
#calendar caption {/*表格标题,也就是日历的第一行,显示年月的地方*/
background-color:#06C;
}
#calendar a{/*超链接样式*/
color:#F90;
margin:0 5px;
text-decoration:none;
}
#calendar #prev_month,#calendar #next_month {/*点击到上一个月,下一个月的两个箭头*/
font-size:18px;
margin:0;
}
#calendar #c_today {/*表格单元格当前天的样式*/
background-color:#036;
color:#FFF;
}
#calendar .over {/*鼠标经过单元格时,显示样式*/
background-color:#CCC;
}
#calendar .keydate {/*关键天显示样式*/
color:#06F;
}

使用说明
例子一:文本框输入控件
1、实例化JCalendar
2、调用JCalendar的实例方法bind邦定文本框,其中可以多次调用bind方法进行邦定多个文本框。
3、调用例子:
window.onload = function(){
var j = new JCalendar();
j.setYears(1990,2020);//设置年份下拉菜单范围为1990年到2020年
j.bind('a',"bottom");
j.bind('b');
}


例子二:网站页面普通的日历
1、实例化JCalendar
2、根据需要调用实例方法setKeyDate来设置关键天的显示,前提是定义好CSS样式,别忘了,样式是一个类,类名叫keydate
3、调用例子:
window.onload = function(){
var j = new JCalendar();
j.setYears(1990,2020);//设置年份下拉菜单范围为1990年到2020年
document.getElementById("calendar_container").innerHTML = j.toString();
j.setKeyDate([1,4,7,14,23,28]);//设置关键天
}
[注意]同一个页面,不能也不会出现两个以上实例(因为程序限制了^_^),即不能同时作为普通日历和输入控件用。
主要原因是用到了很多静态方法。

  • 上一篇文章:
  • 下一篇文章:
  • 关于我们 - 联系我们 - 广告服务 - 在线投稿 - 友情链接 - 网站地图 - 版权声明
    CopyRight 2008-2010, CWYDESIGN.COM - 畅无忧设计, Inc. All Rights Reserved
    滇ICP备09005765号