HTML+JavaScript自己動手做日歷


當我們需要在頁面中顯示某月的事項,或是選擇某一段日期時,常常要使用到日歷組件。這一組件同樣有着許多現成的類庫,然而親自動手開發一個日歷,從中了解其實現原理也是非常必要的。在本例中我們就將制作一款非常經典的日歷組件。

更多精彩內容歡迎訪問我的個人博客皮皮豬:http://www.zhsh666.xyz或者http://www.zh66.club期待您的光臨哦!我是皮皮豬,感謝各位光臨,能為您排憂解難小站深感榮幸!祝您生活愉快!

1. 創建DOM代碼

本例的HTML代碼如下:

<div class="calendar">
  <div class="title">
    <h1 class="green" id="calendar-title">Month</h1>
    <h2 class="green small" id="calendar-year">Year</h2>
    <a href="" id="prev">Prev Month</a>
    <a href="" id="next">Next Month</a>
  </div>
  <div class="body">
    <div class="lightgrey body-list">
      <ul>
        <li>MON</li>
        <li>TUE</li>
        <li>WED</li>
        <li>THU</li>
        <li>FRI</li>
        <li>SAT</li>
        <li>SUN</li>
      </ul>
    </div>
    <div class="darkgrey body-list">
      <ul id="days">
      </ul>
    </div>
  </div>
</div>

由以上代碼可見,日歷的最外層是一個類名為calendar的div元素,其內部包含了兩大部分,分別是日歷頂部的標題區域,其類名為title,以及其下方的日期區域,其類名為body。

在title中包含了當前所選日期的月份、年份,其id分別為calendar-title和calendar-year,此外該元素還包括了prev和next兩個按鈕,分別用於切換選擇上一月和下一月。

在body中首先包含了一個周一到周日的英文表頭,它們放在一個ul元素中。在表頭之后是另一個div元素,用於顯示日歷主體。其中,日歷所選月份的每一天都將顯示在該元素內部的days列表中。

2. CSS樣式

本例中大部分的基礎CSS樣式省略介紹,在此僅介紹其中的body-list類。該類用於設置日歷表頭和日期數據的柵格顯示。我們將整個ul元素的寬度設置為100%,並將其除以7,就可以得到每一個li元素的寬度,即14.28%,將這些元素左浮動顯示,就可以得到日期的7列顯示,樣式代碼如下:

.calendar{
	width:450px;
	height:350px;
	background:#fff;
	box-shadow:0px 1px 1px rgba(0,0,0,0.1);
}
.body-list ul{
	width:100%;
	font-family:arial;
	font-weight:bold;
	font-size:14px;
}
.body-list ul li{
	width:14.28%;
	height:36px;
	line-height:36px;
	list-style-type:none;
	display:block;
	box-sizing:border-box;
	float:left;
	text-align:center;
}

此外,我們為今天、今天之前及今天之后的日期分別創建了不同的類。其中,用淺灰色來顯示過去的日期,深灰色來顯示將來的日期,日期當天則使用淺綠色背景、綠色文字加以顯示,樣式代碼如下:

.lightgrey{
	color:#a8a8a8; /*淺灰色*/
}
.darkgrey{
	color:#565656; /*深灰色*/
}
.green{
	color:#6ac13c; /*綠色*/
}
.greenbox{
	border:1px solid #6ac13c;
	background:#e9f8df; /*淺綠色背景*/
}

日歷組件的初始顯示效果如下圖所示。

3. JavaScript生成日歷

接着使用JavaScript來動態生成日歷信息。首先,我們要做一些前期的准備工作。由於閏年和非閏年的二月天數是不一樣的,在此我們為這兩種年份分別創建數組,以便於獲取每個月的天數,同時為每個月份的英文名創建相應的數組變量,代碼如下:

var month_olympic = [31,29,31,30,31,30,31,31,30,31,30,31];
var month_normal = [31,28,31,30,31,30,31,31,30,31,30,31];
var month_name = ["January","Febrary","March","April","May","June","July","Auguest","September","October","November","December"];

然后,為頁面中的各種元素創建變量,以便於后續的引用,代碼如下:

var holder = document.getElementById("days");
var prev = document.getElementById("prev");
var next = document.getElementById("next");
var ctitle = document.getElementById("calendar-title");
var cyear = document.getElementById("calendar-year");

創建一個Date對象來獲取當前的日期時間,並通過getFullYear()方法來獲取當前年份,getMonth()方法來獲取月份,getDate()方法來獲取當前日期。代碼如下:

var my_date = new Date();
var my_year = my_date.getFullYear();
var my_month = my_date.getMonth();
var my_day = my_date.getDate();

我們要實現日歷的排布,最關鍵的問題是要知道某一月第一天究竟是星期幾,然后才可以根據當月的天數來依次排列其后的日期。在此,專門為該功能創建一個函數,代碼如下:

//獲取某年某月第一天是星期幾
function dayStart(month, year) {
	var tmpDate = new Date(year, month, 1);
	return (tmpDate.getDay());
}

此外,我們也創建一個相應的函數來獲取某月的總天數,代碼如下:

//計算某年是不是閏年,通過求年份除以4的余數即可
function daysMonth(month, year) {
	var tmp = year % 4;
	if (tmp == 0) {
		return (month_olympic[month]);
	} else {
		return (month_normal[month]);
	}
}

然后,創建一個refreshDate函數來生成月份顯示,代碼如下:

function refreshDate(){
	var str = "";
	var totalDay = daysMonth(my_month, my_year); //獲取該月總天數
	var firstDay = dayStart(my_month, my_year); //獲取該月第一天是星期幾
	var myclass;
	for(var i=1; i<firstDay; i++){ 
		str += "<li></li>"; //為起始日之前的日期創建空白節點
	}
	for(var i=1; i<=totalDay; i++){
		if((i<my_day && my_year==my_date.getFullYear() && my_month==my_date.getMonth()) || my_year<my_date.getFullYear() || ( my_year==my_date.getFullYear() && my_month<my_date.getMonth())){ 
			myclass = " class='lightgrey'"; //當該日期在今天之前時,以淺灰色字體顯示
		}else if (i==my_day && my_year==my_date.getFullYear() && my_month==my_date.getMonth()){
			myclass = " class='green greenbox'"; //當天日期以綠色背景突出顯示
		}else{
			myclass = " class='darkgrey'"; //當該日期在今天之后時,以深灰字體顯示
		}
		str += "<li"+myclass+">"+i+"</li>"; //創建日期節點
	}
	holder.innerHTML = str; //設置日期顯示
	ctitle.innerHTML = month_name[my_month]; //設置英文月份顯示
	cyear.innerHTML = my_year; //設置年份顯示
}
refreshDate(); //執行該函數

測試頁面,日歷顯示效果如下圖所示。

4. 添加交互動作

最后,我們為prev和next元素分別創建onclick事件函數,使得每點擊一次prev,則將當前月份減去1,並調用refreshDate函數刷新日歷顯示。當月份數值小於0時,則使年份減去1,並使月份變為11,使日歷顯示為前一年的12月。next的功能與其恰好相反。代碼如下:

prev.onclick = function(e){
	e.preventDefault();
	my_month--;
	if(my_month<0){
		my_year--;
		my_month = 11;
	}
	refreshDate();
}
next.onclick = function(e){
	e.preventDefault();
	my_month++;
	if(my_month>11){
		my_year++;
		my_month = 0;
	}
	refreshDate();
}

測試頁面,日歷中前一月、后一月的切換效果如下圖所示。

下載源文件:https://cloud.ecnu.edu.cn/p/DVF08RwQGRi6Aw

最后,希望這篇文章對大家自定義開發頁面中的日歷組件有所幫助!


免責聲明!

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



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