發新話題

[分享] JCalendar 日曆控件 v1.0 beta[兼容IE&Firefox] 有文檔和例子

JCalendar 日曆控件 v1.0 beta[兼容IE&Firefox] 有文檔和例子

先扯點題外話^_^
從註冊時間來看,我是個老經典人,但是從發帖數來看同時我又是個新經典人。說起來倒是很巧的一件事,我在經典和無憂上註冊的時間居然是同一天!2005-8-16,我依稀記得的是,當時註冊經典是要下載一個東西。之後就一直在無憂上遊蕩,偶爾冒起來問幾個問題。兩年時間,問過不少弱智問題,也解答過一些問題。偶也在無憂的陪伴下從一個小菜鳥變成了一個老菜鳥。近段時間看過的幾篇好文章都是經典裡出的。記得其中一篇就是子虛烏有大大的傑作。我開始關注經典。。。

最近發現無憂人氣在下滑,不知道是我主觀感覺還是。。。不管怎麼說我對無憂都是有感情的,畢竟無憂陪伴我成長了兩年時間。在兩年時間裡面從無憂各位大大身上學到了些東西,也認識了很多牛人,不過他們不認識偶^_^。
現在到經典來,不是想投奔經典,而是想認識更多的腳本高手們。無憂我會一如既往的支持,同時經典也一樣。現在特別為經典奉獻上一件作品,作為偶在經典的第一帖。


前面發佈過一次,那次只能算0.5版本,感興趣的可以到這裡瀏覽 訪客無法瀏覽此圖片或連結,請先 註冊登入會員
現在這個版本在原來的版本上改進的,解釋核心還是一樣的,但增加了一些功能,同時為解釋後的日曆減了一下肥,讓日曆顯示更快速。
主要特點和更新:
1、日曆在實例化的時候,就建好容器,在日曆更改日期的時候不再重建容器,而是循環更新容器裡的內容(也就是日曆裡的數字),讓日曆顯示更快。
2、提供兩個日曆事件,onclick(在點擊某天是觸發),onupdate(在日曆內容更改時觸發)。
3、多用途,可以用作網站一般的日曆使用或者是表單的輸入控件。
4、結構和顯示分離,用戶可以自己定義日曆的樣式,也就是CSS。
5、全局函數定義JCalendar類的靜態方法,避免污染命名空間。
6、年份和月份採用下拉框,而且給用戶提供設置年份範圍的函數。但默認不顯示,點擊年份或月份超鏈接後愛顯示,從而改善界面美觀。
轉載請保留作者信息,謝謝。
偶可以上傳附件了,好人做到底,打包提供下載
經典限制了字數,只能在第二樓放文檔和例子了
更新了一個bug,選擇空白日期時會出現2007-5-NaN[更新時間2007-5-29 12:39]
更新了一個bug,已經選擇了2007年5月20日,想改成2010年5月20日,就點不了了[更新時間2007-5-29 18:58]


目前還在開發中,更多的資訊請到討論區看看喔!
附件: 您所在的用戶組無法下載或查看附件

TOP

文檔+例子
複製內容到剪貼板
代碼:
<!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" />
<title>JCalendar 日曆控件 v1.0 beta</title>
<style type="text/css">
body {
        font-size:12px;
        font-family:'宋體',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 {
        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.__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);
        }
        HTMLDocument.prototype.attachEvent = function(sType,foo){
                this.addEventListener(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日曆控件
*@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;\">&laquo;</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;\">&raquo;</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;
                var contain = $("calendar_container");
                if(isIE){
                        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;
        //更新當前年月
        JCalendar.cur_year = year;
        JCalendar.cur_month = month;
        if(_date) JCalendar.cur_date = _date;
        $("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 = "";
        $("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>
        <fieldset>
                <legend>接口說明</legend>
                <h3>一、JCalendar構造函數</h3>
                <p>
                        參數:<br />
        [、三個表示年月日的整數,比如:new JCalendar(2007-5-18)<br />
        \、一個表示年月日的字串,年月日之間以「-」隔開,比如new JCalendar("2007-5-18")<br />
        ]、空。參數為空,日曆初始化為當前日期。
                </p>
                </h3>
                <h3>二、實例方法</h3>
                <p>
        [、toString()<br />
                        得到解釋後的日曆的HTML代碼<br />
                        參數:無<br />
                        返回:解釋後的日曆的HTML代碼
                </p>
                <p>
        \、setYears(first,last)<br />
                        設置日曆年份下拉菜單的年份範圍<br />
                        參數:<br />
        [、first 第一個年份界限<br />
        \、last 第二個年份界限<br />
                        兩個參數順序可以顛倒
                </p>
                <p>
        ]、bind(obj_id,direction)<br />
                        將日曆邦定到某個文框,當點擊該文本框的時候彈出日曆。<br />
                        日曆的當前日期為文本框裡的日期,如果文本框裡有日期的話。否則就是當前日期<br />
                        參數:<br />
                [、obj_id:文本框的id<br />
                \、direction:控制日曆顯示的方向,[right|bottom]。可以為空,默認為right。<br />
                        right-日曆顯示在文本框的右邊,bottom日曆顯示在文本框下面。<br />
                </p>
                <p>
        ^、setKeyDate(Date_Array)<br />
                        特別顯示關鍵天,典型例子:博客、網絡日誌之類的日曆<br />
                        實現原理,為每個關鍵天的表格單元添加一個class,名字為keydate,CSS樣式需要自己寫,比如加個背景之類的<br />
                        參數:<br />
                                Date_Array:日期的數組,比如:[1,4,6,9]
                </p>
                <h3>三、靜態方法</h3>
                <p>
                        多數靜態方法是控件內部調用的,用戶不應該調用。<br />
                        但是有兩個方法用戶可以覆蓋,也是日曆為用戶提供的兩個事件:<br />
        [、JCalendar.onupdate:在日曆日期更新時觸發,用戶需要自己寫函數覆蓋默認函數<br />
        \、JCalendar.onclick:在日曆日期被點擊時觸發,用戶需要自己寫函數覆蓋默認函數。<br />
                        <span class="red">[注意]用作文本框輸入控件時,不要覆蓋。</span>
                </p>
                <p>
                        當然,用戶可以自己定義自己的日曆樣式,下面是樣式的說明,同時也給出了本人的寫的樣式:<br />
                        #calendar_container {/ *日曆容器,是一個絕對定位的DIV,在日曆作為輸入控件時才有用。作為文本框輸入控件時必須定義這個樣式,而且一定要定義寬度 */ <br />
width:160px;<br />
border:1px solid #06C;<br />
}<br />
#calendar {/*日曆表格樣式,對應的是一個&lt;table&gt;標籤*/<br />
border-collapse:collapse;<br />
background-color:#FFF;<br />
width:160px;<br />
height:120px;<br />
margin:0px auto;<br />
cursor:default;<br />
}<br />
#calendar td {/*很明顯,這是一個表格單元*/<br />
text-align:center;<br />
vertical-align:middle;<br />
font-family:"宋體";<br />
}<br />
#calendar thead {/*表格頭,也就是顯示日一二三四五六那行*/<br />
background-color:#999;<br />
color:#FFF;<br />
}<br />
#calendar caption {/*表格標題,也就是日曆的第一行,顯示年月的地方*/<br />
background-color:#06C;<br />
}<br />
#calendar a{/*超鏈接樣式*/<br />
color:#F90;<br />
margin:0 5px;<br />
text-decoration:none;<br />
}<br />
#calendar #prev_month,#calendar #next_month {/*點擊到上一個月,下一個月的兩個箭頭*/<br />
font-size:18px;<br />
margin:0;<br />
}<br />
#calendar #c_today {/*表格單元格當前天的樣式*/<br />
background-color:#036;<br />
color:#FFF;<br />
}<br />
#calendar .over {/*鼠標經過單元格時,顯示樣式*/<br />
background-color:#CCC;<br />
}<br />
#calendar .keydate {/*關鍵天顯示樣式*/<br />
color:#06F;<br />
} <br />
</p>
        </fieldset>
        <fieldset>
                <legend>使用說明</legend>
                <h3>例子一:文本框輸入控件</h3>
                <p>
        [、實例化JCalendar<br />
        \、調用JCalendar的實例方法bind邦定文本框,其中可以多次調用bind方法進行邦定多個文本框。<br />
        ]、調用例子:<br />
                        window.onload = function(){<br />
                        var j = new JCalendar();<br />
                        j.setYears(1990,2020);//設置年份下拉菜單範圍為1990年到2020年<br />
                        j.bind('a',"bottom");<br />
                        j.bind('b');<br />
                        }<br />
                </p>
                <h3>例子二:網站頁面普通的日曆</h3>
                <p>
        [、實例化JCalendar<br />
        \、根據需要調用實例方法setKeyDate來設置關鍵天的顯示,前提是定義好CSS樣式,別忘了,樣式是一個類,類名叫keydate<br />
        ]、調用例子:<br />
                        window.onload = function(){<br />
                        var j = new JCalendar();<br />
                        j.setYears(1990,2020);//設置年份下拉菜單範圍為1990年到2020年<br />
                        document.getElementById("calendar_container").innerHTML = j.toString();<br />
                        j.setKeyDate([1,4,7,14,23,28]);//設置關鍵天<br />
                        }<br />
                        <span class="red">[注意]同一個頁面,不能也不會出現兩個以上實例(因為程序限制了^_^),即不能同時作為普通日曆和輸入控件用。</span><br />
                        主要原因是用到了很多靜態方法。
                </p>
        </fieldset>
        <fieldset>
                <legend>一個作為輸入控件的例子</legend>
                <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">&nbsp;</p>
                <p class="center">&nbsp;</p>
                <p class="center">&nbsp;</p>
                <p class="center">&nbsp;</p>
        </fieldset>
</body>
</html>

TOP

給兩個純例子,方便不想看文檔的人
普通日曆例子
複製內容到剪貼板
代碼:
<!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" />
<title>JCalendar 日曆控件 v1.0 beta</title>
<style type="text/css">
body {
        font-size:12px;
        font-family:'宋體',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 {
        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.__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);
        }
        HTMLDocument.prototype.attachEvent = function(sType,foo){
                this.addEventListener(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日曆控件
*@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;\">&laquo;</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;\">&raquo;</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;
                var contain = $("calendar_container");
                if(isIE){
                        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;
        //更新當前年月
        JCalendar.cur_year = year;
        JCalendar.cur_month = month;
        if(_date) JCalendar.cur_date = _date;
        $("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 = "";
        $("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);
        document.getElementById("calendar_container").innerHTML = j.toString();
        j.setKeyDate([1,8,12,26]);
        JCalendar.onclick=function(){location="http://bbs.51js.com"};
        JCalendar.onupdate=function(){location="http://bbs.51js.com"};
}
</script>

</head>
<body>
<div id="calendar_container"></div>
</body>
</html>

TOP

用作輸入控件的例子
複製內容到剪貼板
代碼:
<!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:'宋體',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 {
        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;\">&laquo;</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;\">&raquo;</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;
                var contain = $("calendar_container");
                if(isIE){
                        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;
        //更新當前年月
        JCalendar.cur_year = year;
        JCalendar.cur_month = month;
        if(_date) JCalendar.cur_date = _date;
        $("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 = "";
        $("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">&nbsp;</p>
                <p class="center">&nbsp;</p>
                <p class="center">&nbsp;</p>
                <p class="center">&nbsp;</p>
</body>
</html>

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。