zoukankan      html  css  js  c++  java
  • 日历控件,可运行在XHTML1.0下

    JCalendar.js

      1 //////////////////基本函数库/////////////////////////////
      2 var isIE = /msie/i.test(navigator.userAgent);
      3 var isDTD = /CSS1Compat/i.test(document.compatMode);
      4 if(!isIE){
      5  window.constructor.prototype.__defineGetter__("event",function(){
      6   var func = arguments.callee.caller;
      7   while(func != null){
      8    var arg0 = func.arguments[0];
      9    if(arg0 && (arg0.constructor==Event || arg0.constructor ==MouseEvent)){
     10     return arg0;
     11    }
     12    func = func.caller;
     13   }
     14      return null;
     15  });
     16  Event.prototype.__defineSetter__("returnValue",function(b){
     17   if(!b)this.preventDefault();
     18   return b;
     19  });
     20  Event.prototype.__defineGetter__("srcElement",function(){
     21   var node=this.target;
     22   while(node.nodeType != 1)node=node.parentNode;
     23   return node;
     24  });
     25  Event.prototype.__defineGetter__("offsetX",function(){
     26    return this.layerX;
     27  });
     28  Event.prototype.__defineGetter__("offsetY",function(){
     29   return this.layerY;
     30  });
     31  HTMLElement.prototype.attachEvent = function(sType,foo){
     32   this.addEventListener(sType.slice(2),foo,false);
     33  }
     34  HTMLElement.prototype.detachEvent = function(sType,foo){
     35   this.removeEventListener(sType.slice(2),foo,false);
     36  }
     37  HTMLDocument.prototype.attachEvent = function(sType,foo){
     38   this.addEventListener(sType.slice(2),foo,false);
     39  }
     40  HTMLDocument.prototype.detachEvent = function(sType,foo){
     41   this.removeEventListener(sType.slice(2),foo,false);
     42  }
     43  HTMLElement.prototype.__defineGetter__("innerText",function(){
     44   return this.textContent;
     45  });
     46  HTMLElement.prototype.__defineSetter__("innerText",function(str){
     47   this.textContent = str;
     48  });
     49 }
     50 else document.execCommand("BackgroundImageCache",false,true);
     51 function $(id){return (typeof id == "string" ? document.getElementById(id) : id);}
     52 function $N(name){return document.getElementsByName(name);}
     53 function $TN(name,root){return root ? $(root).getElementsByTagName(name) : document.getElementsByTagName(name);}
     54 function $DC(name){return document.createElement(name);}
     55 function exist(id){return $(id)!= null;}
     56 function hide(){
     57  for(var i = 0; i < arguments.length; i++){
     58   if(exist(arguments[i])){
     59    if($(arguments[i]).style.visibility) $(arguments[i]).style.visibility = "hidden";
     60    else $(arguments[i]).style.display = "none";
     61   }
     62  }
     63 }
     64 function show(){
     65  for(var i = 0; i < arguments.length; i++){
     66   if(exist(arguments[i])){
     67    if($(arguments[i]).style.visibility) $(arguments[i]).style.visibility="visible";
     68    else $(arguments[i]).style.display = "";
     69   }
     70  }
     71 }
     72 //////////////JCalendar 类////////////////////////////
     73 /***************************
     74  *JCalendar日历控件
     75  *@author brull
     76  *@email [email]brull@163.com[/email]
     77  *@date 2007-4-16
     78  *@更新 2007-5-27
     79  *@version 1.0 beta
     80  ***************************/
     81 /*
     82  *@param year 年份,[可选]
     83  *@param month 月份,[可选]
     84  *@param date 日期,[可选]
     85  *或者是以横线间隔开的日期,比如:2007-4-27
     86  */
     87  
     88 function JCalendar (year,month,date) {
     89  if($("calendar"))return;//唯一实例
     90  var _date = null;
     91  if(arguments.length == 3) _date = new Date(year,month-1,date);
     92  else if(arguments.length == 1 && typeof arguments[0] == "string")
     93   _date = eval("new Date(" + arguments[0].split("-").join() + ")");
     94  //如果没有参数,就初始化为当天日期
     95  else if(arguments.length == 0) _date = new Date();
     96  this.year = _date.getFullYear();
     97  this.month = _date.getMonth() + 1;
     98  this.date = _date.getDate();
     99  this.FIRSTYEAR = 1949;
    100  this.LASTYEAR = 2049;
    101  JCalendar.cur_year = this.year;
    102  JCalendar.cur_month = this.month;
    103  JCalendar.cur_date = this.date;
    104  JCalendar.cur_obj_id = null;//作为输入控件时保存当前文本框的id
    105 }
    106 /**
    107  *设置日历年份下拉菜单的年份范围
    108  *@first 第一个年份界限
    109  *@last 第二个年份界限
    110  *两个参数顺序可以颠倒
    111  */
    112 JCalendar.prototype.setYears = function(first,last){
    113  if(isNaN(first) || isNaN(last)) return;
    114  this.FIRSTYEAR = Math.min(first,last);
    115  this.LASTYEAR = Math.max(first,last);
    116 }
    117 /**
    118  *以HTML串返回日历控件的HTML代码
    119  */
    120 JCalendar.prototype.toString = function(){
    121  var fday = new Date(this.year,this.month-1,1).getDay();//每月第一天的星期数
    122  var select_year = new Array();//年份下拉菜单
    123  var select_month = new Array();//月份下拉菜单
    124  //日历里的每个单元格的数据,预先定义一段空数组,对应日历里第一周空的位置。[注意星期天对应的数是0]
    125  var date = new Array(fday > 0 ? fday - 1 : 0);
    126  var dayNum = new Date(this.year,this.month,0).getDate();//每月的天数
    127  var html_str = new Array();//保存日历控件的HTML代码
    128  var date_index = 0;//date数组的索引
    129  var weekDay = ["日","一","二","三","四","五","六"];
    130  
    131  //填充年份下拉菜单
    132  select_year.push("<select id='select_year'  style='display:none' onblur ="hide(this);show('title_year')" onchange='JCalendar.update(this.value,JCalendar.cur_month)'>");
    133  for(var i = this.FIRSTYEAR; i <= this.LASTYEAR; i++){
    134   if(i == this.year)
    135    select_year.push("<option value='" + i + "' selected='selected'>" + i +"</option>");
    136   else
    137    select_year.push("<option value='" + i + "'>" + i +"</option>");
    138  }
    139  select_year.push("</select>");
    140  
    141  //填充月份下拉菜单
    142  select_month.push("<select  id='select_month' style='display:none'  onblur ="hide(this);show('title_month')" onchange='JCalendar.update(JCalendar.cur_year,this.value)'>");
    143  for(var i = 1; i <= 12; i++){
    144   if(i == this.month)
    145    select_month.push("<option value='" + i + "' selected='selected'>" + i +"月</option>");
    146   else
    147    select_month.push("<option value='" + i + "'>" + i +"月</option>");
    148  }
    149  select_month.push("</select>");
    150  //初始化date数组
    151  for(var j = 1; j <= dayNum; j++){
    152   date.push(j);
    153  }
    154  //开始构建日历控件的HTML代码
    155  html_str.push("<table id='calendar'>");
    156  //日历表格caption
    157  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>");
    158  //日历表格头
    159  html_str.push("<thead><tr>");
    160  for(var i = 0; i < 7; i++){//填充日历头
    161   html_str.push("<td>" + weekDay[i] + "</td>");
    162  }
    163  html_str.push("</tr></thead>");
    164  //日历主体
    165  var tmp;
    166  html_str.push("<tbody>");
    167  for(var i = 0; i < 6; i++){//填充日期,6行7列
    168   html_str.push("<tr>");
    169   for(var j = 0; j < 7; j++){
    170    tmp = date[date_index++];
    171    if(!tmp) tmp = "";
    172    html_str.push("<td ");
    173    if(tmp == this.date) html_str.push("id='c_today' ");
    174    html_str.push("onmouseover='JCalendar.over(this)' onmouseout='JCalendar.out(this)' onclick='JCalendar.click(this)'>" + tmp + "</td>");
    175   }
    176   html_str.push("</tr>");
    177  }
    178  html_str.push("</tbody></table>");
    179  return html_str.join("");
    180 }
    181 /**
    182  *特别显示关键天,典型例子博客的日历
    183  * 实现原理,为每个关键天的表格单元添加一个class,名字为keydate,CSS样式需要自己写,比如加个背景之类的
    184  *@param 日期的数组,比如:[1,4,6,9]
    185  */
    186 JCalendar.prototype.setKeyDate = function(){
    187  var dates = arguments[0];
    188  var tds = $TN("td",$("calendar"));
    189  var reg = null;
    190  for(var i = 0; i < dates.length; i++){
    191   reg = new RegExp("\b" + dates[i] + "\b");
    192   for(var j = 7; j < tds.length; j++){//忽略表格头
    193    if(reg.test(tds[j].innerText)){
    194     tds[j].className = "keydate";
    195     break;
    196    }
    197   }
    198  }
    199 }
    200 /**
    201  *可以将日历控件邦定到某个文本框,在点击文本框的时候,会在direction指定的方向弹出日历,可以多次调用来帮定多个文本框
    202  *@ param obj_id 需要邦定日历的文本框的id
    203  *@ param direction 日历出现的相对于文本框的方向 [可选] 默认为right
    204  */
    205 JCalendar.prototype.bind = function(obj_id,direction){
    206  var obj = $(obj_id);
    207  var direction = direction ? direction : "right";
    208  if(!obj)return;
    209  if(!$("calendar_container")){//唯一容器
    210   var contain = $DC("div");
    211   var s = contain.style;
    212   s.visibility = "hidden";
    213   s.position = "absolute";
    214   s.top = "0px";//不能占据页面空间
    215   s.zIndex = 65530;
    216   contain.id = "calendar_container";
    217   contain.innerHTML = this.toString();
    218   document.body.appendChild(contain);
    219   if(isIE){
    220    var ifm = $DC("iframe");
    221    var s = ifm.style;
    222    ifm.frameBorder = 0;
    223    ifm.height = (contain.clientHeight - 3) + "px";
    224    s.visibility = "inherit";
    225    s.filter = "alpha(opacity=0)";
    226    s.position = "absolute";
    227    s.top = "0px";//不能占据页面空间
    228    s.width = $("calendar_container").offsetWidth;
    229    s.zIndex = -1;
    230    contain.insertAdjacentElement("afterBegin",ifm);
    231   }
    232  }
    233  //覆盖日历事件
    234  JCalendar.onupdate = function () {};
    235  JCalendar.onclick = function (year,month,date){
    236   $(JCalendar.cur_obj_id).value = $(JCalendar.cur_obj_id).value.replace(/^[^s]*/i,year + '-' + month + '-' + date);
    237   hide("calendar_container");
    238  }
    239  //邦定事件
    240  document.attachEvent("onclick",function(){
    241   if($("calendar_container").style.visibility="visible")hide("calendar_container");
    242  });
    243  obj.attachEvent("onclick",function(e){
    244   var obj = e.srcElement;
    245   var dates =obj.value.split(/s/)[0].split("-");//文本框日期数组,文本框内容可能有时间这样的字串,即:2007-5-26 15:39
    246   var left = obj.offsetLeft , top = obj.offsetTop;
    247   var x,y,left,top;
    248   var contain = $("calendar_container");
    249   var body = isDTD ? document.documentElement : document.body;
    250   left = body.scrollLeft + e.clientX - e.offsetX;
    251   top = body.scrollTop + e.clientY - e.offsetY;
    252   switch(direction){
    253    case "right" : x = left + obj.offsetWidth; y = top;break;
    254    case "bottom" : x = left; y = top + obj.offsetHeight;break;
    255   }
    256   contain.style.top = y + "px";
    257   contain.style.left = x + "px";
    258   //更新日历日期
    259   if(dates.length == 3 && (JCalendar.cur_year != dates[0] || JCalendar.cur_month != dates[1] || JCalendar.cur_date != dates[2]))
    260    JCalendar.update(dates[0],dates[1],dates[2]);//如果文本框有时间则更新时间到文本框的时间
    261   else if (dates.length != 3){
    262    var now = new Date();
    263    JCalendar.update(now.getFullYear(),now.getMonth() + 1,now.getDate());
    264   }
    265   if($("calendar_container").style.visibility="hidden")show("calendar_container");
    266   e.cancelBubble = true;
    267   JCalendar.cur_obj_id = obj.id;
    268  });
    269  $("calendar_container").attachEvent("onclick",function(e){e.cancelBubble = true;});
    270 }
    271 /*===========================静态方法=======================================*/
    272 /**
    273  *更新日历内容
    274  */
    275 JCalendar.update = function(_year,_month,_date){
    276  date = new Date(_year,_month-1,1);
    277  var fday = date.getDay();//每月第一天的星期数
    278  var year = date.getFullYear();
    279  var month = date.getMonth() + 1;
    280  var dayNum = new Date(_year,_month,0).getDate();//每月的天数
    281  var tds = $TN("td",$("calendar"));
    282  var years = $("select_year").options;
    283  var months = $("select_month").options;
    284  var _date = _date ? _date : JCalendar.cur_date;
    285  //更新当前年月
    286  JCalendar.cur_year = year;
    287  JCalendar.cur_month = month;
    288  if(_date && _date <= dayNum) JCalendar.cur_date = _date;
    289  else if(_date > dayNum) JCalendar.cur_date = _date - dayNum;
    290  $("title_year").innerText = year + "年";
    291  $("title_month").innerText = month + "月";
    292  //更新年份下拉菜单选中项
    293  for(var i = years.length - 1; i >= 0; i-- ){
    294   if(years[i].value == year){
    295    $("select_year").selectedIndex = i;
    296    break;
    297   }
    298  }
    299  //更新月份下拉菜单选中项
    300  for(var i = months.length - 1; i >= 0; i-- ){
    301   if(months[i].value == month){
    302    $("select_month").selectedIndex = i;
    303    break;
    304   }
    305  }
    306  //清空日历内容,忽略日历头,即第一行
    307  for(var i = 7; i < tds.length; i++) tds[i].innerText = "";
    308  if( $("c_today"))$("c_today").removeAttribute("id");
    309  for(var j = 1; j <= dayNum; j++){
    310   tds[6 + fday + j].innerText = j;
    311   if(j == JCalendar.cur_date) tds[6 + fday + j].id = "c_today";
    312  }
    313  JCalendar.onupdate(year,month,JCalendar.cur_date);
    314 }
    315 JCalendar.click = function(obj){
    316  var tmp = $("c_today");
    317  if(tmp && tmp == obj){
    318   JCalendar.onclick(JCalendar.cur_year,JCalendar.cur_month,JCalendar.cur_date);
    319  }
    320  else if(obj.innerText != ""){
    321   if(tmp) tmp.removeAttribute("id");
    322   JCalendar.cur_date = parseInt(obj.innerText);
    323   obj.id = "c_today";
    324   JCalendar.onclick(JCalendar.cur_year,JCalendar.cur_month,JCalendar.cur_date);
    325  }
    326 }
    327 JCalendar.over = function(obj){
    328  if(obj.innerText != "") obj.className = "over";
    329 }
    330 JCalendar.out = function(obj){
    331  if(obj.innerText != "") obj.className = "";
    332 }
    333 //日历更改时执行的函数,可以更改为自己需要函数,控件传递过来的参数为当前日期
    334 JCalendar.onupdate = function(year,month,date){
    335  alert("日历已更改,当前日历日期:" + year + "年" + month + "月" + date + "日");
    336 }
    337 //点击日期时执行的函数,可以更改为自己需要函数,控件传递过来的参数为当前日期
    338 JCalendar.onclick = function(year,month,date){
    339  alert( "当前触发的日期:" + year + "年" + month + "月" + date + "日");
    340 }
    341 function showCalendar (obj) 
    342 {
    343     var j = new JCalendar();
    344     j.setYears(1990, 2020);
    345     j.bind(obj, "bottom");
    346     //j.bind('b');
    347 }
    View Code

    Calendar.css

     1 /**********日历样式开始********************/
     2 #calendar_container {
     3  width:160px;
     4  border:1px solid #06C;
     5 }
     6 #calendar {
     7  border-collapse:collapse;
     8  background-color:#FFF;
     9  width:160px;
    10  height:120px;
    11  margin:0px auto;
    12  cursor:default;
    13 }
    14 #calendar td {
    15  font-size:12px;
    16  text-align:center;
    17  vertical-align:middle;
    18  font-family:"宋体";
    19 }
    20 #calendar thead {
    21  background-color:#999;
    22  color:#FFF;
    23 }
    24 #calendar caption {
    25  background-color:#06C;
    26 }
    27 #calendar a{
    28  color:#F90;
    29  margin:0 5px;
    30  text-decoration:none;
    31 }
    32 #calendar #prev_month,#calendar #next_month {
    33  font-size:18px;
    34  margin:0;
    35 }
    36 #calendar #c_today {
    37  background-color:#036;
    38  color:#FFF;
    39 }
    40 #calendar .over {
    41  background-color:#CCC;
    42 }
    43 #calendar .keydate {
    44  color:#06F;
    45 }
    View Code

    页面调用:

     <link href="calendar.css" type="text/css" rel="stylesheet" />
     <script language="javascript" src="JCalendar.js" type="text/javascript"> </script>
     <input type="text"  onclick='showCalendar(this)' />
  • 相关阅读:
    理解 RESTful:理论与最佳实践
    Shiro 性能优化:解决 Session 频繁读写问题
    单点登录的三种实现方式
    理解 Spring(二):AOP 的概念与实现原理
    理解 Spring(一):Spring 与 IoC
    MFC查内存泄漏方法
    024 --- 第28章 访问者模式
    023 --- 第27章 解释器模式
    022 --- 第26章 享元模式
    021 --- 第25章 中介者模式
  • 原文地址:https://www.cnblogs.com/pushaoxia/p/3237952.html
Copyright © 2011-2022 走看看