javascript中Date對象的應用之簡易日歷的實現方法

javascript中Date對象的應用——簡易日歷的實現

簡易日歷作為javascript中Date對象的常見應用,用途較廣泛。本文將詳細說明簡易日歷的實現思路

效果演示

HTML說明

  使用type=number的兩個input分別作為年和月的輸入控件,這樣在高級瀏覽器下自帶調節按鈕

  按照周日到周一的順序進行星期的排列

<p class="box">
    </p><header class="control">
        <input id="conYear" class="con-in" type="number" min="1900" max="2100" step="1" >="" <input="" <="" header="">
    <p class="DateBox">
        </p><header class="week">
            <p class="week-in">周日</p>
            <p class="week-in">周一</p>
            <p class="week-in">周二</p>
            <p class="week-in">周三</p>
            <p class="week-in">周四</p>
            <p class="week-in">周五</p>
            <p class="week-in">周六</p>
        </header>
        <section class="dayBox" id="dayBox">
            <p class="day" id="day1">1</p>
            <p class="day">2</p>
            <p class="day">3</p>
            <p class="day">4</p>
            <p class="day">5</p>
            <p class="day">6</p>
            <p class="day">7</p>
            <p class="day">8</p>
            <p class="day">9</p>
            <p class="day">10</p>
            <p class="day">11</p>
            <p class="day">12</p>
            <p class="day">13</p>
            <p class="day">14</p>
            <p class="day">15</p>
            <p class="day">16</p>
            <p class="day">17</p>
            <p class="day">18</p>
            <p class="day">19</p>
            <p class="day">20</p>
            <p class="day">21</p>
            <p class="day">22</p>
            <p class="day">23</p>
            <p class="day">24</p>
            <p class="day">25</p>
            <p class="day">26</p>
            <p class="day">27</p>
            <p class="day">28</p>
            <p class="day">29</p>
            <p class="day" id="day30">30</p>
            <p class="day" id="day31">31</p>
        </section>
    <p></p>    
<p></p></header>

CSS說明

  對於簡易日歷的實現,首先確定日歷中class="day"的p的排列方式為浮動。這樣可以通過改變第一天p的位置,來實現所有同級p都可以跟隨移動的效果

body{
    margin: 0;
}
input{
    border: none;
    padding: 0;
}
.box{
    width: 354px;
    margin: 30px auto 0;    
}
.DateBox{
    height: 300px;
    border: 2px solid black;
}    
.week{
    overflow: hidden;
    border-bottom: 1px solid black;
    line-height: 49px;
}
.week-in{
    height: 49px;
    float: left;
    width: 50px;
    text-align: center;
}
.dayBox{
    overflow: hidden;
}
.day{
    float: left;
    height: 50px;
    width: 50px;
    font:20px/50px '微軟雅黑';
    text-align: center;
}
.control{
    overflow: hidden;
}
.con-in{
    height: 50px;
    float: left;
    width: 100px;
    text-align: center;
    font: 20px/50px "微軟雅黑";
}

JS說明

  簡易日歷的JS邏輯總共需要5個實現:

  【1】需要獲取當月的天數,獲取當月第一天、第30天、第31天是周幾

  【2】根據當月第一天的星期,改變第一天的margin-left值,移動第一天到對應的位置;由於浮動的關系,其餘天也會跟著移動到對應的位置

  【3】根據當月的天數,隱藏多餘的天;當然,隱藏之前要先顯示在其他月份可能被隱藏的天

  【4】如果當月30日是周日,則會新占一行。這時通過改變30日這天的margin值將其移動到第一行(若31日可能會新占一行,也做相似處理)

  【5】載入頁面後,獲取當前的年和月,顯示當月日歷;當改變年或月時,獲取改變後的值,更新日歷

//準備:獲取當前樣式
function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
}
//實現一:獲取當月的天數,及當月第一天、第30日、第31日是星期幾
function get_data(year,month){
    var result = {};
    var d = new Date();
    //如果是2月
    if(month == 2){
        //如果是閏年
        if((year % 4 === 0 && year % 100 !== 0)  || year % 400 === 0){
            result.days = 29;
        //如果是平年
        }else{
            result.days = 28;
        }
    //如果是第4、6、9、11月
    }else if(month == 4 || month == 6 ||month == 9 ||month == 11){
        result.days = 30;
    }else{
        result.days = 31;
        //當月第31天是星期幾
        result.day31week = d.getDay(d.setFullYear(year,month-1,31));
    }
    //當月第一天是星期幾
    result.day1week = d.getDay(d.setFullYear(year,month-1,1));
    if(month != 2){
        //當月第30天是星期幾
        result.day30week = d.getDay(d.setFullYear(year,month-1,30));        
    }
    return result;
}
//實現二:根據當月第一天的星期x,設置第一天的margin-left=寬度*x,使其對應到正確的星期位置上
function move_day1(year,month){
    var week1 = get_data(year,month).day1week;
    day1.style.marginLeft = week1%7*parseInt(getCSS(day1,'width'))+ 'px';
}
//實現三:根據當月的天數,來隱藏多餘的天數。當然首先要先顯示在其他月份被隱藏的天數
function hide_days(year,month){
    //恢復其他月份可能隱藏的天數
    for(var i = 28; i<31; i++){
        dayBox.children[i].style.display = 'block';
    }    
    //隱藏當月多餘的天數
    var days = get_data(year,month).days;
    for(var i = days;i<31;i++){
        dayBox.children[i].style.display = 'none';
    }
};
//實現四:如果當月30日或31日是星期日,則會新占一行,通過設置margin-top把新占一行的天移動到第一行
function move_day30(year,month){
    //如果當月30日是星期日
    if(get_data(year,month).day30week === 0){
        day30.style.marginTop = parseInt(getCSS(day30,'height')) *(-5) + 'px';
        day31.style.marginTop = parseInt(getCSS(day31,'height')) *(-5) + 'px';
        day31.style.marginLeft= getCSS(day31,'width');
        return;
    }else{
        day30.style.marginTop = day31.style.marginTop = day31.style.marginLeft ='0';
    }
    //如果當月31日是星期日
    if(get_data(year,month).day31week === 0){
        day31.style.marginTop = parseInt(getCSS(day31,'height')) *(-5) + 'px';
    }else{
        day31.style.marginTop = '0';
    }
}
//實現五:當載入頁面時,獲取當前年和月,顯示當月日歷;當改變年或月時,獲取改變後的年和月,更新當月日歷
var year= conYear.value=new Date().getFullYear();
var month= conMonth.value = new Date().getMonth() + 1;
move_day1(year,month);
hide_days(year,month);
move_day30(year,month);

conYear.onchange = conMonth.onchange = function(){
    var year = conYear.value;
    var month = conMonth.value;
    if(year<1900 || year >2100 ){
        year = conYear.value=new Date().getFullYear();
    }
    if(month<1 || month > 12){
        month = conMonth.value=new Date().getMonth() + 1;
    }
    move_day1(year,month);
    hide_days(year,month);
    move_day30(year,month);
}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *