29 | /**
30 | * Created by SongYuting .
31 | */
32 |
33 | /**
34 | * @summary 当前日期
35 | * @desc 用于记录当前日历状态的Date对象,随用户的操作而不断更新
36 | * @type {Date}
37 | */
38 | var currentDate = new Date();
39 |
40 | /**
41 | * @summary 今日日期
42 | * @desc 用于记录今日信息的Date对象,创建后不改变,供“回到今天”使用
43 | * @type {Date}
44 | */
45 | var today = new Date();
46 | var thisMonth = today.getMonth();
47 | var thisYear = today.getFullYear();
48 | //newCalendar(thisYear, thisMonth);
49 |
50 | /**
51 | * @summary 今日日期
52 | * @desc 在操作日期发生改变时,记录上一次操作后的日期,与currentDate相差一次操作,供日期切换使用
53 | * @type {Date}
54 | */
55 | var datedDate;//
56 |
57 |
58 | //初始生成日历
59 | newCalendar();
60 |
61 | /**
62 | *
63 | * “上一年”切换按钮监听
64 | */
65 | var btnLastYear = document.getElementById("lastYear");
66 | btnLastYear.addEventListener("click", function() {
67 | var currentYear = currentDate.getFullYear();
68 | currentDate.setYear( --currentYear );
69 | newCalendar();
70 | }, false);
71 |
72 | /**
73 | *
74 | * “下一年”切换按钮监听
75 | */
76 | var btnNextYear = document.getElementById("nextYear");
77 | btnNextYear.addEventListener("click", function() {
78 | var currentYear = currentDate.getFullYear();
79 | currentDate.setYear( ++currentYear );
80 | newCalendar();
81 | }, false);
82 |
83 | /**
84 | *
85 | * “上个月”切换按钮监听
86 | */
87 | var btnLastMonth = document.getElementById("lastMonth");
88 | btnLastMonth.addEventListener("click", function() {
89 | var currentMonth = currentDate.getMonth();
90 | currentDate.setMonth( --currentMonth );
91 | newCalendar();
92 | }, false);
93 |
94 | /**
95 | *
96 | * “下个月”切换按钮监听
97 | */
98 | var btnNextMonth = document.getElementById("nextMonth");
99 | btnNextMonth.addEventListener("click", function() {
100 | var currentMonth = currentDate.getMonth();
101 | currentDate.setMonth( ++currentMonth);
102 | newCalendar();
103 | }, false);
104 |
105 | /**
106 | *
107 | * “回到今天”切换按钮监听
108 | */
109 | var btnBackToday = document.getElementById("backToday");
110 | btnBackToday.addEventListener("click", function() {
111 | var nowTime = today.getTime();
112 | currentDate.setTime(nowTime);
113 | newCalendar();
114 | }, false);
115 |
116 | var dateNav = document.getElementsByClassName("date");
117 |
118 |
119 | /**
120 | * @summary 根据指定 年-月(格式:YYYY-MM)生成当月日历
121 | * @desc 主体部分。
122 | * 利用Date的构造函数调用参数,
123 | * 当数值大于合理范围时,会被调整为相邻值,以此获取此月日历中第一行第一列的日期。
124 | * 若指定月份的1号是周日,表明日历不含上月的日期,无需特殊处理;
125 | * 若指定月份的1号不是周日,则取相反数(原理: 1 - 周几 + 1),获取所需日期。
126 | * 注:此处为方便生成表格使用(++date),日期计数取为从0开始,即1号由0表示,与Date.prototype.getDate()所得相差1。
127 | * 灵感来源:{@link http://jszen.blogspot.com/2007_07_01_archive.html}
128 | * @param {number} year - 预生成日历的年份
129 | * @param {number} month - 预生成日历的月份
130 | * @returns {date} currentDate - 当前日期(仅年份、月份发生改变)
131 | *
132 | */
133 | function newCalendar() {
134 | var month = currentDate.getMonth();
135 | var year = currentDate.getFullYear();
136 | var date = currentDate.getDate();
137 | var thisMonthDay = new Date(year, month, 1);
138 | var thisMonthFirstDay = thisMonthDay.getDay();
139 | var thisMonthFirstDate = new Date(year, month, - thisMonthFirstDay);
140 | generateTable(thisMonthFirstDate); //生成日历主体的日期区域
141 | generateNav(year, month); //生成导航区域
142 | generateToday(); //生成今日信息区域
143 | currentDate.setYear(year);
144 | currentDate.setMonth(month);
145 | return currentDate;
146 | }
147 |
148 | /**
149 | * @summary 设定导航区域
150 | * @desc 利用年、月设定相关值
151 | * @param {number} year - 预生成日历的年份
152 | * @param {number} month - 预生成日历的月份
153 | * @todo 加入实时变化的时间
154 | *
155 | */
156 | function generateNav(year, month) {
157 | var navYear = document.getElementById("year");
158 | var navMonth = document.getElementById("month");
159 | navYear.innerText = year.toString();
160 | navMonth.innerText = (month + 1).toString();
161 | }
162 |
163 | /**
164 | * @summary 根据日历首位日期,生成日历主体表格
165 | * @desc 首位日期指:日历的表格中第一行第一列位置的日期。
166 | * 利用Date的相关特性处理跨月份的情况,循环后
167 | * 生成 6*7 表格,加入DOM树,形成日历的主体日期区域。
168 | * @param {date} firstDate - 日历表格中第一行、第一列的日期数(从0开始)
169 | */
170 | function generateTable(firstDate) {
171 | //获取日历日期部分Node
172 | var dateTable = document.getElementById("dateTable");
173 | //若不是第一次生成,则需要把此前生成的日历去掉
174 | while (dateTable.firstChild) {
175 | dateTable.removeChild(dateTable.firstChild);
176 | }
177 | var date = firstDate.getDate();
178 | for (var i = 0; i < 6; i++){
179 | var newRow = document.createElement("tr");
180 | for(var j = 0; j < 7; j++){
181 | var newDate = document.createElement("td");
182 | //获取日期信息
183 | firstDate.setDate(++date);
184 | date = firstDate.getDate();
185 | newDate.innerText = date;
186 | //设置Node的id,便于后期操作
187 | var dateInfo = firstDate.toLocaleDateString();
188 | newDate.setAttribute("id",dateInfo);
189 | newDate.setAttribute("class", "date");
190 | //设置点击事件,防止被解释为数字,用转义字符加上双引号
191 | newDate.setAttribute("onclick", "generateToday(\"" + dateInfo+ "\")");
192 | newRow.appendChild(newDate);
193 | }
194 | dateTable.appendChild(newRow);
195 | }
196 | }
197 |
198 | /**
199 | *
200 | * @summary 根据具体日期,生成/切换今日详细信息
201 | * @desc 在进行日期切换时,点击某个日期或“回到今天”,根据生成日历时设置的id,修改今日信息区域,相关信息随之改变
202 | * @param {string} dateString - 表示日期的字符串,格式 YYYY/MM/DD
203 | * @todo 获取星座、宜&忌、农历天干地支等信息
204 | */
205 | function generateToday(dateString) {
206 | if(dateString){ //若传递了参数,根据参数设定值
207 | var info = dateString.split("/");
208 | currentDate.setYear(info[0]); //坑:切换日期跨月时很容易出错
209 | if( currentDate.getDate() > 30) {
210 | currentDate.setDate(info[2]);
211 | currentDate.setMonth(parseInt(info[1])-1 );
212 | }else {
213 | currentDate.setMonth(parseInt(info[1])-1 );
214 | currentDate.setDate(info[2]);
215 | }
216 | }
217 | if( datedDate == null){
218 | //第一次生成
219 | datedDate = new Date();
220 | }else{
221 | //获取前一次操作时涉及的元素,清除样式
222 | var datedDateString = datedDate.toLocaleDateString();
223 | document.getElementById(datedDateString).setAttribute("class","date");
224 | }
225 | var dateInfo = currentDate.toLocaleDateString(); //获取YYYY/MM/DD格式的日期
226 | var dayNum = currentDate.getDate(); //获取日期号数
227 | var weekInfo = currentDate.getDay();
228 | var weekArray = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
229 | document.getElementById("dateInfo").innerText = dateInfo; //DOM操作日期
230 | document.getElementById("dateNum").innerText = dayNum.toString(); //DOM操作号数
231 | document.getElementById("weekInfo").innerText = weekArray[weekInfo];
232 | var dateTd = document.getElementById(dateInfo);
233 | dateTd.setAttribute("class","todayTd"); //设定新的CSS样式
234 | // 记录此次操作的日期
235 | datedDate.setYear(currentDate.getFullYear()); //坑:这里的顺序不能颠倒,否则切换月的时候会错
236 | datedDate.setMonth(currentDate.getMonth());
237 | datedDate.setDate(currentDate.getDate());
238 | }
239 |
240 |