實現博客園的日歷效果的原生js插件


   這個原生代碼的js日歷插件是根據我前面的那個生成日歷效果的函數改造而成的,原本以為利用我前面那個日歷函數可以很容易就實現博客園一樣效果的日歷插件,但事實上還是費了一般的功夫才實現這個博客園效果的日歷插件,個中遇到的問題就不一一敘述了,只講兩點。

  我本以為這個時間插件的點擊事件是比較容易實現的,但,動手時才發現,點擊事件並不好綁定,剛開始,我是把日歷全部都放在一個table里面。我以為這樣子生成一個日歷更簡單,點擊事件也應該不難實現,但現實是,嘗試了很多次都不成功,原因是:點擊再次生成日歷時,綁定在table的事件作用在自己的身上,同時也作用在事件自己的身上,所以很難實現點擊事件,也就很難再次生成下一個日歷或者上一個日歷了。鑒於此,我選擇事件和日歷分做兩部分來實現,這才比較簡單的實現了這個插件。

  整個插件的思路是這樣的:

  ①、首先,生成一個日歷的div,這個div用來存儲''''''點擊事件的div''''''和'''''日歷的table'''''。

  ②、生成一個存儲點擊事件的div,這個div用來存放日歷的年份和月份,同時也用來存儲點擊事件。

  ③、生成一個存儲月份日期的日歷table,不用說,這個table就是用來存放月份的每個日期的。

  實現的思維比較簡單,我js的代碼注釋的很詳細,大家可以仔細看一下,思路都在注釋中,這里就不再重復了。

  這個插件的優點(比博客園的好一點的是):有日歷月份的前導零,還有就是,高亮顯示當前日期,呵呵,也就這么多了。

  不過,因為本人的css樣式不怎地,所以,需要改樣式的,讀者可以親自動手,因為樣式是動態生成的,所以,讀者可以任意修改。

  下面是calendar.js插件文件的代碼。

//js日歷
(function(){
var calendar = function(calendarId){
    //日歷對象不存在,返回日歷
    if(!(this instanceof calendar)){
        return new calendar();
    }
    //獲取當前日歷對象
    var c =this;
    //獲取引用日歷的節點id,這是外面提供的要放哪里的id
    var calendarId = document.getElementById(calendarId);
    //動態加載樣式
    function loadStyles(str){
        loadStyles.mark = 'load';
        var style = document.createElement("style");
        style.type = "text/css";
        try{
            style.innerHTML = str;
        }catch(ex){
            style.styleSheet.cssText = str;
        }
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(style); 
    }
    //生成節點的函數
    c.buildPart = function(json){
        var oPart = document.createElement(json.node);
        if(json.id){oPart.setAttribute('id',json.id);}
        if(json.className){oPart.className = json.className;}
        if(json.innerHTML){oPart.innerHTML = json.innerHTML;}
        if(json.href){oPart.setAttribute('href',json.href);}
        if(json.appendToBox){
            json.appendToBox.appendChild(oPart);
        }
        return oPart;
    }
    //全局初始化日期表格tr字符串
    var CalendarTr;
    //獲取當前的日期,為的是高亮顯示當前的日期
    var today = new Date().getDate();
    var thisyear =  new Date().getFullYear();
    var thismonth =  new Date().getMonth()+1;
    //生成日歷的函數
    c.getcalendar = function(year,month){
        var last = new Date(year,month-1,0);//獲取上個月份的時間對象
        var lastdate = last.getDate();//獲取上個月的最大日期
        var lastday = last.getDay();//獲取上個月最大日期的星期幾
        var months = new Date(year,month,0);
        var Maxdate = months.getDate();//獲取這個月最大的日期
        //星期表頭
        var str = '<tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr>';
        //獲取上個月在這個月份中存在的最后日期
        var remainlastdate = lastdate - lastday;
        var t = 1;
        //日歷的日期
        str += '<tr>';
        for(var g=0;g<=6;g++){
        //星期是從0開始到6結束的,小於等於上個月最大星期的日期則是上個月的日期
            if(g <= lastday){
                str +='<td class="Tr">'+ remainlastdate++ +'</td>';
            }else{
                //高亮顯示當前日期
                if(thisyear == year && thismonth == month && today == t){
                    str +='<td class="redTr">'+ t++ +'</td>';
                //假如不是當前月份則默認1為高亮日期
                }else if((thisyear != year && t == 1) || (thismonth != month && t == 1)){
                    str +='<td class="redTr">'+ t++ +'</td>';
                }else{
                //該月份的普通日期
                    str +='<td class="blueTr">'+ t++ +'</td>';
                }
            }
        }
        str += '</tr>';
        //除去上面的部分,這個月從哪里開始
        var remainlastday = 6 - lastday + 1;
        var nextMonthday = 1;//下一個月份的開始日期
        //這里i最大值為5是為了兼容所有的月份,有的月份可能跨越6個tr
        for(var i=1;i<=5;i++){
            str += '<tr>';
            for(var j=0;j<7;j++){
                if(remainlastday <= Maxdate){
                    if(thisyear == year && thismonth == month && today == remainlastday){
                    str +='<td class="redTr">'+ remainlastday++ +'</td>';
                    }else{
                        if((thisyear != year && remainlastday == 1) || (thismonth != month && remainlastday == 1)){
                            //剩下的天數從這里開始的話,默認的第一天還是為紅色
                            str +='<td class="redTr">'+ remainlastday++ +'</td>';
                        }else{
                            str +='<td class="blueTr">'+ remainlastday++ +'</td>';
                        }
                    }
                }else{
                    str +='<td class="Tr">'+ nextMonthday++ +'</td>';
                }
            }
            str += '</tr>';
        }
        return str;
    }
    //初始化內部構造函數
    c.init = function(){
        //生成日歷的表格tr
        CalendarTr = c.getcalendar(thisyear,thismonth);
        if(loadStyles.mark != 'load'){
        loadStyles(".calendarDiv {width:361px;text-align:center;}\
            .Table{width:360px;height:200px;}\
            .box{margin-left:15px;margin-right:10px;text-align:center;width:335px;height:22px;font-weight:bold;font-size:21px;}\
            .box-dec{border:none;text-align:left;cursor:pointer;font-weight:bold;float:left;}\
            .box-add{border:none;text-align:right;cursor:pointer;font-weight:bold;float:right;}\
            .Tr{text-align:center;}\
            .redTr{color:red;text-align:center;}\
            .blueTr{color:blue;text-align:center;};");
        }
        //生成整個日歷的div,包括年月份的div和日歷表格都放在這個div里面
        c.buildPart({
            node : 'div',
            id : 'calendarDiv',
            className : 'calendar',
            appendToBox : calendarId//整個日歷添加到提供進來的要放日歷的id里面
        });
        //生成存儲日歷的年月份的div
        c.buildPart({
            node : 'div',
            id : 'headId',
            className : 'box',
            appendToBox : calendarDiv
        });
        //生成存儲減少月份的span
        c.buildPart({
            node : 'span',
            id : 'dec',
            className : 'box-dec',
            innerHTML : '\<',
            appendToBox : headId
        });
        //生成存儲年份的span
        c.buildPart({
            node : 'span',
            id : 'Year',
            innerHTML : thisyear + '年',
            appendToBox : headId
        });
        //生成存儲月份的span
        c.buildPart({
            node : 'span',
            id : 'Month',
            innerHTML : thismonth < 10 ? '0'+ thismonth + '月' : thismonth,
            appendToBox : headId
        });
        //生成存儲增加月份的div
        c.buildPart({
            node : 'span',
            id : 'add',
            className : 'box-add',
            innerHTML : '\>',
            appendToBox : headId
        });
        //生成存儲日歷的table
        c.buildPart({
            node : 'table',
            id : 'calendarTable',
            className : 'Table',
            innerHTML : CalendarTr,
            appendToBox : calendarDiv
        });
    }
    //內部初始化日歷生成
    c.init();
    //日歷的事件部分
    (function(){
        var dec = document.getElementById('dec');
        var add = document.getElementById('add');
        var Month = document.getElementById('Month');
        var Year = document.getElementById('Year');
        var Tr = document.getElementById('calendarTable');
        month = parseInt(Month.innerHTML);
        year = parseInt(Year.innerHTML);
        //設置月份減少的點擊事件
        dec.onclick = function(e){
            e = e || event;
            var target = e.target || e.srcElement;
            if(target.id == 'dec'){
                if(month>1 || month== 12){
                    Month.innerHTML = --month < 10 ? '0' + month+ '月': month+ '月';
                    CalendarTr = c.getcalendar(year,month);
                    Tr.innerHTML = '';
                    Tr.innerHTML = CalendarTr;
                }else{
                    Year.innerHTML  = --year <=1970 ? 1970 + '年' : year + '年';
                    Month.innerHTML = year < 1970 && month < 2 ? '01月': 12 + '月';
                    //小於1970的時間顯示為1970的時間
                    if(year < 1970 && month < 2){
                        year = 1970,month=1;
                        CalendarTr = c.getcalendar(year,month);
                        Tr.innerHTML = '';
                        Tr.innerHTML = CalendarTr;
                    }else{
                        month = 12;
                        CalendarTr = c.getcalendar(year,month);
                        Tr.innerHTML = '';
                        Tr.innerHTML = CalendarTr;
                    }
                    
                }
            }
        }
        //設置月份增加的點擊事件
        add.onclick = function(e){
            e = e || event;
            var target = e.target || e.srcElement;
            if(target.id == 'add'){
                if(month>0 && month<12){
                    Month.innerHTML = ++month < 10 ? '0' + month+ '月': month+ '月';
                    CalendarTr = c.getcalendar(year,month);
                    Tr.innerHTML = '';
                    Tr.innerHTML = CalendarTr;
                }else{
                    Year.innerHTML  = ++year + '年';
                    Month.innerHTML = '0'+1 + '月';
                    month = 1;
                    CalendarTr = c.getcalendar(year,month);
                    Tr.innerHTML = '';
                    Tr.innerHTML = CalendarTr;
                }
            }
        }    
    })();
}
window.calendar = calendar;
})();

  引用方式很簡單,只需引入這個js插件,然后,實例化calendar實例即可,傳入的參數為html對象的id,舉個例子如下

<!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" xml:lang="zh-cn">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    <title>calendar日歷插件</title>
    <meta name="keywords" content="關鍵字列表" />
    <meta name="description" content="網頁描述" />
    <link rel="stylesheet" type="text/css" href="" />
    <style type="text/css"></style>
    <script type="text/javascript" src='http://www.test.com/time/calendar.js'></script>
</head>
<body>
<div id='calen'></div>
</body>
</html>
<script>
//只需實例化calendar實例即可,傳入的參數為html對象的id,舉個例子如下
new calendar('calen');
</script>

  要是對插件中生成日期的那部分不理解可以查看我的歷史文章,《一個js簡單的日歷顯示效果的函數》這篇文章有詳細介紹,地址:

http://www.cnblogs.com/loveyoume/p/6239475.html

  要是對你有用,可以打賞一下作者呢,感激不盡。假如有bug,還望讀者指出,謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM