标签:style blog http color java 使用 io strong
一、分析日历的组成部分和交互要素
(1)组成部分:选择年月部分、星期显示、包含本月(或者有前月和下一个月部分日子)
(2)根据选择的年和月份,动态绘制日历面板。
(3)一个日历 7(天) * 5(周) = 35格表格。
(4)一个月份是统一的一个面板;一个月的头一天一定在日历面板的第一行,根据该天的“星期几”确定位置。
(5)第一格子是星期一,最后一个格子是星期日,为5周的日历面板。
二、确定逻辑设计
日历上面的日历,8月1号建军节为什么会出现在这一格?因为一个月的天数是小于5周(35天)的,因此,在第一行肯定包含了一个月份的第一天,而这一天的位置是根据该天的星期几来确定的,比如7月的1号是星期二,那么7月1号在第一行的星期二的位置上,然后依次类推,计算前一个月在面板上显示的日期,下一个月在面板上显示的日期。
可以将每一个表格看成是一个日期对象,那么下一步的目的就是根据传入不同年份和月份,计算出面板上显示的日期对象数组。
三、构建日历类
(1)首先,构建一个可以传入DOM DIV的日历类。
1 var Calendar = function(div){ 2 this.div = document.getElementById(div); 3 }; 4 5 Calendar.week = [‘星期一‘, ‘星期二‘,‘星期三‘, ‘星期四‘,‘星期五‘, ‘星期六‘, ‘星期日‘]; 6 Calendar.month = [‘1月‘,‘2月‘,‘3月‘,‘4月‘,‘5月‘,‘6月‘,‘7月‘,‘8月‘,‘9月‘,‘10月‘,‘11月‘,‘12月‘];
(2)日历面板逻辑实现。
一个日历面板包含3个日期对象数组,第一个是preMonth,因为,也许该日历面板上会显示前一个月的一些日期;第二个是本月的日期currentMonth;第三个是下一个月的日期数组,nextMonth。定义一个函数monthPanel代表一个日历面板,返回值是三个数组合并的对象。
如何计算前一个月会显示多少日期?首先计算选择的月份的第一天在第一行(从0开始计算)占据着第几个位置(4),然后上一个月的总天数(31)减去该位置向上索取,即31-4,31-3,31-2,31-1,31.,那么结果就是31-4,31-3,31-2,31-1,31, 1。
如何计算下一个月会显示多少日期?很好办,总共35个格子,那么35 - 当前月份的天数 - 当前月份占据的位置n+1 就是要显示的下一个的日期格子数。
综合后的代码如下:
1 Calendar.prototype.monthPanel = function(date){ 2 //如果传递了Date对象,则按Date对象进行计算月份面板 3 //否则,按照当前月份计算面板 4 var date = date || new Date(), 5 year = date.getFullYear(), 6 month = date.getMonth(), 7 day = date.getDate(), 8 week = date.getDay(), 9 currentDays = new Date(year, month + 1, 0).getDate(), 10 preDays = new Date(year, month, 0).getDate(), 11 firstDay = new Date(year, month, 1), 12 firstCell = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1, 13 bottomCell = 35 - currentDays - firstCell; 14 //前一个月该显示多少天 15 var preMonth = []; 16 for(var p = firstCell; p > 0; p--){ 17 preMonth.push(new Date(year, month - 1, preDays - p + 1)); 18 } 19 //本月 20 var currentMonth = []; 21 for(var c = 0; c < currentDays; c++){ 22 currentMonth.push(new Date(year, month, c + 1)); 23 } 24 //下一个月 25 var nextMonth = []; 26 for(var n = 0; n < bottomCell; n++){ 27 nextMonth.push(new Date(year, month + 1, n + 1)); 28 } 29 30 preMonth = preMonth.concat(currentMonth, nextMonth); 31 return preMonth; 32 };
(3)检测代码逻辑是否正确,正好在使用node cmd,所以索性在node下运行了(当如放到Chrome console也可以),不过需要先注释掉this.div = document.getElementById(div);这一行。var c = new Calendar();console.log(c.monthPanel(new Date(2014, 6, 1))); 其实不传递参数,就是显示当前月份的日历面板。如下图。
三、构建最基础的UI
(1)动态绘制35个表格
1 for(var i = 0; i < 35; i++){ 2 var cellDOM = document.createElement(‘div‘); 3 cellDOM.style.width = cell.width + ‘px‘; 4 cellDOM.style.height = cell.height + ‘px‘; 5 cellDOM.style.display = ‘inline-block‘; 6 cellDOM.style.float = ‘left‘; 7 cellDOM.style.border = ‘1px solid blue‘; 8 cellDOM.style.cursor = ‘pointer‘; this.div.appendChild(cellDOM); 11 }
(2)显示日期和月份的头部
1 Calendar.prototype.showUI = function(date){ 2 var width = this.div.style.width || 800, 3 height = this.div.style.height || (600 - 30), 4 cell = {width: (parseInt(width) - 20)/7, height: (parseInt(height) -30 - 20)/5}, 5 monthArr = this.monthPanel(date); 6 7 this.addHeader(date); 8 for(var i = 0; i < 35; i++){ 9 var cellDOM = document.createElement(‘div‘); 10 cellDOM.style.width = cell.width + ‘px‘; 11 cellDOM.style.height = cell.height + ‘px‘; 12 cellDOM.style.display = ‘inline-block‘; 13 cellDOM.style.float = ‘left‘; 14 cellDOM.style.border = ‘1px solid blue‘; 15 cellDOM.style.cursor = ‘pointer‘; 16 cellDOM.innerHTML = monthArr[i].getDate(); 17 this.div.appendChild(cellDOM); 18 } 19 20 }; 21 22 Calendar.prototype.addHeader = function(date){ 23 var header = document.createElement(‘div‘); 24 header.style.height = ‘20px‘; 25 header.style.width = this.div.style.width || ‘800px‘; 26 header.style.textAlign = ‘center‘; 27 header.style.fontWeight = ‘bold‘; 28 header.innerHTML = date.getFullYear() + ‘年‘ + (date.getMonth() + 1) + ‘月‘; 29 console.log(header); 30 this.div.appendChild(header); 31 }
(3)编写HTML和整个逻辑代码
HTML:
<!doctype html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="calendar.js"></script> <script type="text/javascript"> function showCalendar(){ var c = new Calendar(‘calendar‘); c.showUI(new Date()); } </script> </head> <body onload="showCalendar()"> <div id="calendar" style="width:600px; height:400px;border:1px solid red;"></div> </body> </html>
javascript:
1 var Calendar = function(div){ 2 this.div = document.getElementById(div); 3 }; 4 5 Calendar.week = [‘星期一‘, ‘星期二‘,‘星期三‘, ‘星期四‘,‘星期五‘, ‘星期六‘, ‘星期日‘]; 6 Calendar.month = [‘1月‘,‘2月‘,‘3月‘,‘4月‘,‘5月‘,‘6月‘,‘7月‘,‘8月‘,‘9月‘,‘10月‘,‘11月‘,‘12月‘]; 7 8 Calendar.prototype.showUI = function(date){ 9 var width = this.div.style.width || 800, 10 height = this.div.style.height || (600 - 30), 11 cell = {width: (parseInt(width) - 20)/7, height: (parseInt(height) -30 - 20)/5}, 12 monthArr = this.monthPanel(date); 13 14 this.addHeader(date); 15 for(var i = 0; i < 35; i++){ 16 var cellDOM = document.createElement(‘div‘); 17 cellDOM.style.width = cell.width + ‘px‘; 18 cellDOM.style.height = cell.height + ‘px‘; 19 cellDOM.style.display = ‘inline-block‘; 20 cellDOM.style.float = ‘left‘; 21 cellDOM.style.border = ‘1px solid blue‘; 22 cellDOM.style.cursor = ‘pointer‘; 23 cellDOM.innerHTML = monthArr[i].getDate(); 24 this.div.appendChild(cellDOM); 25 } 26 27 }; 28 29 Calendar.prototype.addHeader = function(date){ 30 var header = document.createElement(‘div‘); 31 header.style.height = ‘20px‘; 32 header.style.width = this.div.style.width || ‘800px‘; 33 header.style.textAlign = ‘center‘; 34 header.style.fontWeight = ‘bold‘; 35 header.innerHTML = date.getFullYear() + ‘年‘ + (date.getMonth() + 1) + ‘月‘; 36 console.log(header); 37 this.div.appendChild(header); 38 } 39 40 Calendar.prototype.monthPanel = function(date){ 41 //如果传递了Date对象,则按Date对象进行计算月份面板 42 //否则,按照当前月份计算面板 43 var date = date || new Date(), 44 year = date.getFullYear(), 45 month = date.getMonth(), 46 day = date.getDate(), 47 week = date.getDay(), 48 currentDays = new Date(year, month + 1, 0).getDate(), 49 preDays = new Date(year, month, 0).getDate(), 50 firstDay = new Date(year, month, 1), 51 firstCell = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1, 52 bottomCell = 35 - currentDays - firstCell; 53 //前一个月该显示多少天 54 var preMonth = []; 55 for(var p = firstCell; p > 0; p--){ 56 preMonth.push(new Date(year, month - 1, preDays - p + 1)); 57 } 58 //本月 59 var currentMonth = []; 60 for(var c = 0; c < currentDays; c++){ 61 currentMonth.push(new Date(year, month, c + 1)); 62 } 63 //下一个月 64 var nextMonth = []; 65 for(var n = 0; n < bottomCell; n++){ 66 nextMonth.push(new Date(year, month + 1, n + 1)); 67 } 68 69 preMonth = preMonth.concat(currentMonth, nextMonth); 70 return preMonth; 71 };
基本效果,最为基本的日历逻辑已经完成,可以传入不同的月份,显示日历面板了:
下一篇:增加日历的UI效果 & 添加交互(根据选择,显示日历面板)
javascript动手写日历组件(1)——构建日历逻辑 (by vczero),布布扣,bubuko.com
javascript动手写日历组件(1)——构建日历逻辑 (by vczero)
标签:style blog http color java 使用 io strong
原文地址:http://www.cnblogs.com/vczero/p/js_ui_1.html