国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JS學習之一個簡易的日歷控件

2019-11-21 00:38:33
字體:
來源:轉載
供稿:網友
這個日歷控件類似于園子用的日歷,如下圖:

js 簡易的日歷控件   

 這種日歷控件實現起來不難,下面簡單分析下我的思路:

 首先,是該控件的可配置項:

復制代碼 代碼如下:

...
settings:
{
firstDayOfWeek: 1,
baseClass: "calendar",
curDayClass: "curDay",
prevMonthCellClass: "prevMonth",
nextMonthCellClass: "nextMonth",
curMonthNormalCellClass: "",
prevNextMonthDaysVisible: true
},
...
weekDayNames: [],
...

    其中有一半是用來控制單元格樣式的(不做過多描述),另外幾個(firstDayOfWeek,prevNextMonthDaysVisible,weekDayNames),意義如下:
     firstDayOfWeek:日歷以星期幾做為第一天
     prevNextMonthDaysVisible:是否顯示本月之外的日期
     weekDayNames:星期的名稱(一個索引從1開始的數組,1處的值將作為周一的顯示名稱,以此類推)

     接下來,進入生成html代碼階段:
    1.生成日歷頭:    
復制代碼 代碼如下:

_RenderTitle: function(month, year) {
var ht = [];
//日期
ht.push("<tr>");
ht.push("<th colspan='7' style='width:100%;'><div style='float:left;width:10%;text-align:center;' id='", this.containerId, "_prevMonth' title='上一月'><</div><div style='float:left;text-align:center;width:80%'>", year, "年", month, "月</div><div style='float:right;width:10%; text-align:center;' id='", this.containerId, "_nextMonth' title='下一月'>></div></th>");
ht.push("</tr>");
//星期
ht.push("<tr>");
for (var i = 0; i < 7; i++) {
var day = (i + this.settings.firstDayOfWeek) == 7 ? 7 : (i + this.settings.firstDayOfWeek) % 7;
ht.push("<th>", this.weekDayNames[day], "</th>")
}
ht.push("</tr>");
return ht.join("");
},

    日期部分為操作‘按鈕'的id使用日歷控件容器的id 作為前綴,以保證id唯一。
    星期部分根據firstDayOfWeek的設置來獲取weekDayName。這里關鍵在于判斷每個單元格代表星期幾,思路很簡單:
    var day = (i + this.settings.firstDayOfWeek) == 7 ? 7 : (i + this.settings.firstDayOfWeek) % 7;
    這樣就可以取得當前單元格代表的星期了。

    2.生成日歷的主要部分:
復制代碼 代碼如下:

_RenderBody: function(month, year) {
var date = new Date(year, month - 1, 1);
var day = date.getDay();
var dayOfMonth = 1;
var daysOfPrevMonth = (7 - this.settings.firstDayOfWeek + day) % 7;
var totalDays = this._GetTotalDays(month, year);
var totalDaysOfPrevMonth = this._GetToalDaysOfPrevMonth(month, year);
var ht = [];
var curDate;
for (var i = 0; ; i++) {
curDate = null;
if (i % 7 == 0) {//新起一行
ht.push("<tr>");
}
ht.push("<td");
if (i >= daysOfPrevMonth && dayOfMonth <= totalDays) {//本月
curDate = new Date(year, month - 1, dayOfMonth);
if (Date.parse(new Date().toDateString()) - curDate == 0) {
ht.push(" class='", this.settings.curDayClass, "'");
}
else {
ht.push(" class='", this.settings.curMonthNormalCellClass, "'");
}
dayOfMonth++;
}
else if (i < daysOfPrevMonth) {//上月
if (this.settings.prevNextMonthDaysVisible) {
var prevMonth = month;
var prevYear = year;
if (month == 1) {
prevMonth = 12;
prevYear = prevYear - 1;
}
else {
prevMonth = prevMonth - 1;
}
curDate = new Date(prevYear, prevMonth - 1, totalDaysOfPrevMonth - (daysOfPrevMonth - i - 1));
ht.push(" class='", this.settings.prevMonthCellClass, "'");
}
}
else {//下月
if (this.settings.prevNextMonthDaysVisible) {
var nextMonth = month;
var nextYear = year;
if (month == 12) {
nextMonth = 1;
nextYear = prevYear + 1;
}
else {
nextMonth = nextMonth + 1;
}
curDate = new Date(nextYear, nextMonth-1, i - dayOfMonth - daysOfPrevMonth + 2);
ht.push(" class='", this.settings.nextMonthCellClass, "'");
}
}
ht.push(">");
ht.push(this._BuildCell(curDate));
ht.push("</td>");
if (i % 7 == 6) {//結束一行
ht.push("</tr>");
}
if (i % 7 == 6 && dayOfMonth - 1 >= totalDays) {
break;
}
}
return ht.join("");
},

    (1).獲取該月一號代表星期幾。這樣才能判斷1號應該放到哪個單元格,也就是該月從哪個單元格開始(創建日期的時候month減了1,這是由于js Date對象本身的特性)。
    (2).定義了一個標識變量 dayOfMonth ,用于控制本月日期顯示區域。
    (3).計算要展示的上月的天數以及上月的總天數(不用計算下月要展示的天數和總天數,因為下月要展示的日期是從1開始,最多不會超過6)。
    (4).顯示本月的日期:
    條件i >= daysOfPrevMonth && dayOfMonth <= totalDays決定了本月日期的顯示區域。
    (5).顯示上月日期:
    當i < daysOfPrevMonth 時即為上月日期的顯示區域。
    (6). (4)、(5)之外當然就是下月日期的顯示區域了。
    (7).何時結束:
     從代碼看到for循環是沒有終止條件的,因此必須自己決定何時退出循環:
復制代碼 代碼如下:

     if (i % 7 == 6 && dayOfMonth - 1 >= totalDays) {
break;
}

     i % 7 == 6表示一行結束, dayOfMonth - 1 >= totalDays表示本月日期已經展示完畢。
    (8).構造curDate:
curDate代表每個單元格對應的日期。
在顯示本月日期時, curDate = new Date(year, month - 1, dayOfMonth);
在顯示上月日期時, curDate = new Date(prevYear, prevMonth-1, totalDaysOfPrevMonth - (daysOfPrevMonth - i - 1));
在顯示下月日期時, curDate = new Date(nextYear, nextMonth-1, i - dayOfMonth - daysOfPrevMonth + 2),加2是由于i是從0開始,本身就少了1,dayOfMonth 在退出顯示本月日期時多加了一次.
    最后,再來看看_BuildCell做了什么事情:
復制代碼 代碼如下:

_BuildCell: function(curDate) {
var ht = [];
if (curDate) {
for (var j = 0; j < this.dateLinkMappings.length; j++) {
if (Date.parse(this.dateLinkMappings[j].Date) - curDate == 0) {
ht.push("<a href='", this.dateLinkMappings[j].Link, "'>", curDate.getDate(), "</a>");
break;
}
}
if (j == this.dateLinkMappings.length) {
ht.push(curDate.getDate());
}
}
else {
ht.push(" ");
}
return ht.join("");
},

    事實上本日歷控件的意圖是用戶可以在初始化時傳入日期和該日期對應的鏈接的映射的數組,也就是this.dateLinkMappings,當構建單元格時若正在構建的日期包含在this.dateLinkMappings里,則將當前單元格構造成<a>形式,否則為普通的文本形式。

    OK,實現邏輯大致如此,篇末看下演示效果:
前臺調用代碼如下:
復制代碼 代碼如下:

var date = new Date();
var mapping = [];
mapping.push(new DateLinkMapping("3-22-2010", "javascript:alert(1)"));
mapping.push(new DateLinkMapping("4-1-2010", "javascript:alert(1)"))
Calendar.Init(null, mapping);
Calendar.RenderCalendar("myCalendar", date.getMonth() + 1, date.getFullYear());

打包下載地址

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鸡东县| 余庆县| 芒康县| 合水县| 定远县| 大竹县| 渭南市| 山西省| 寻乌县| 永德县| 宁化县| 延安市| 孙吴县| 靖宇县| 鹤庆县| 深圳市| 晋宁县| 长武县| 那坡县| 宿州市| 临高县| 洪洞县| 云浮市| 化德县| 建瓯市| 河池市| 贵定县| 扶绥县| 东兰县| 永顺县| 佛学| 青田县| 诏安县| 凤翔县| 壤塘县| 彰化市| 潮州市| 玉屏| 北宁市| 辰溪县| 长汀县|