码迷,mamicode.com
首页 > 编程语言 > 详细

javascript动手写日历组件(2)——优化UI和添加交互(by vczero)

时间:2014-08-10 21:32:20      阅读:334      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   java   使用   io   

一、优化UI

继上一篇,http://www.cnblogs.com/vczero/p/js_ui_1.html。开始优化UI,主要优化的部分有:

(1)增加星期行。(2)字体设置。(3)日期垂直居中。(4)将单元格->底部线条。(5)修改文本的颜色对比。(6)将内部调用的函数加前缀_,如_addHeader()、_addWeekday()。

修改的后基本效果如下图:

bubuko.com,布布扣

整个代码做了小修小改:

 1 var Calendar = function(div){
 2     this.div = document.getElementById(div);
 3     this.width = this.div.style.width || 800; //增加两变量
 4     this.height = this.div.style.height || (600 - 30);
 5 };
 6 
 7 Calendar.week = [‘星期一‘, ‘星期二‘,‘星期三‘, ‘星期四‘,‘星期五‘, ‘星期六‘, ‘星期日‘];
 8 Calendar.month = [‘1月‘,‘2月‘,‘3月‘,‘4月‘,‘5月‘,‘6月‘,‘7月‘,‘8月‘,‘9月‘,‘10月‘,‘11月‘,‘12月‘];
 9 
10 Calendar.prototype.showUI = function(date){
11     var width = this.width,
12         height = this.height,
13         cell = {width: (parseInt(width) - 20)/7, height: (parseInt(height) -30 - 20)/5},
14         monthArr = this._monthPanel(date);
15     this.div.style.paddingLeft = ‘8px‘; 
16     this.div.style.border = ‘2px solid #57ABFF‘;
17     this.div.style.cursor = ‘default‘;
18     this.div.style.fontFamily = ‘微软雅黑‘;
19     this._addHeader(date);
20     this._addWeekday();
21     for(var i = 0; i < 35; i++){
22         var cellDOM = document.createElement(‘div‘);
23         cellDOM.style.width = cell.width + ‘px‘;
24         cellDOM.style.height = cell.height + ‘px‘;
25         cellDOM.style.display = ‘inline-block‘;
26         cellDOM.style.float = ‘left‘;
27         cellDOM.style.cursor = ‘pointer‘;
28         cellDOM.style.textAlign = ‘center‘;
29         cellDOM.style.lineHeight = cell.height + ‘px‘;
30         cellDOM.innerHTML = monthArr[i].getDate();
31         //去掉最后一行横线
32         if(i < 28){
33             cellDOM.style.borderBottom = ‘1px solid #C8CACC‘;
34         }
35 
36         this.div.appendChild(cellDOM);
37     }
38     
39 };
40 
41 Calendar.prototype._addHeader = function(date){
42     var header = document.createElement(‘div‘);
43     header.style.height = ‘20px‘;
44     header.style.width = this.div.style.width || ‘800px‘;
45     header.style.textAlign = ‘center‘;
46     header.style.fontWeight = ‘bold‘;
47     header.innerHTML = date.getFullYear() + ‘年‘ + (date.getMonth() + 1) + ‘月‘;
48     console.log(header);
49     this.div.appendChild(header);
50 }
51 
52 //增加星期
53 Calendar.prototype._addWeekday = function(){
54     for(var i = 0; i < 7; i++){
55         var weekday = document.createElement(‘div‘);
56         weekday.style.width = (parseInt(this.width) - 20)/7 + ‘px‘;
57         weekday.style.height = ‘20px‘;
58         weekday.style.display = ‘inline-block‘;
59         weekday.style.float = ‘left‘;
60         weekday.style.color = ‘#BFBFBF‘;
61         weekday.style.fontWeight = ‘bold‘;
62         weekday.innerHTML = Calendar.week[i];
63         this.div.appendChild(weekday);
64     }
65 }
66 
67 Calendar.prototype._monthPanel = function(date){
68     //如果传递了Date对象,则按Date对象进行计算月份面板
69     //否则,按照当前月份计算面板
70     var date = date || new Date(),
71         year = date.getFullYear(),
72         month = date.getMonth(),
73         day = date.getDate(),
74         week = date.getDay(),
75         currentDays = new Date(year, month + 1, 0).getDate(),
76         preDays = new Date(year, month, 0).getDate(),
77         firstDay = new Date(year, month, 1),
78         firstCell = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1,
79         bottomCell =  35 - currentDays - firstCell;
80     //前一个月该显示多少天
81     var preMonth = [];
82     for(var p = firstCell; p > 0; p--){
83         preMonth.push(new Date(year, month - 1, preDays - p + 1));
84     }
85     //本月
86     var currentMonth = [];
87     for(var c = 0; c < currentDays; c++){
88         currentMonth.push(new Date(year, month, c + 1));
89     }
90     //下一个月
91     var nextMonth = [];
92     for(var n = 0; n < bottomCell; n++){
93         nextMonth.push(new Date(year, month + 1, n + 1));
94     }
95 
96     preMonth = preMonth.concat(currentMonth, nextMonth);
97     return preMonth;
98 };

二、增加交互,选中返回日期对象

(1)点击日期,返回日期对象。

要想点击日期,返回日期对象,必须动态的添加事件。因此,需要在每个日期的DIV格子上添加事件,因此,会在创建cellDOM的时候添加事件监听。如下代码和图已经可以根据鼠标点击事件返回时间了。

 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.cursor = ‘pointer‘;
 8         cellDOM.style.textAlign = ‘center‘;
 9         cellDOM.style.lineHeight = cell.height + ‘px‘;
10         cellDOM.setAttribute(‘date‘,monthArr[i]); //设置日期对象到DOM属性date上
11         cellDOM.innerHTML = monthArr[i].getDate();
12         //去掉最后一行横线
13         if(i < 28){
14             cellDOM.style.borderBottom = ‘1px solid #C8CACC‘;
15         }
16 
17         cellDOM.addEventListener(‘click‘, function(event){
18             console.log(this.getAttribute(‘date‘)); //通过this获取当前DOM的属性
19         });
20         this.div.appendChild(cellDOM);
21     }

bubuko.com,布布扣

(2)封装事件,提供返回时间的接口

在Calendar的原型上定义个一个函数Calendar.prototype.getDate = null;暴露这个类函数,让开发者重写这个函数即可。

        <script type="text/javascript">
            function showCalendar(){
                var c = new Calendar(‘calendar‘);
                c.getDate = function(event){
                    alert(new Date(this.getAttribute(‘date‘)));
                };
                c.showUI(new Date());
            }
        </script>

(3)根据选择不同的月份,显示不同的日期面板

这时,就需要一个this.date对象,作为实例的属性,保证修改了this.date对象,其他原型函数也很获取到改变后的数值。下面最为重要的就是根据不同月份,重绘日历面板了。修改代码,增加向左,向右的月份控制。

向左(前一个月)的代码:

 1     var _that = this; //获取到this对象
 2     leftDiv.addEventListener(‘click‘, function(event){
 3         var year = parseInt(_that.date.getFullYear()),
 4             month = parseInt(_that.date.getMonth());
 5         if(month === 0){
 6             _that.date = new Date(year - 1, 11, 1);
 7         }else{
 8             _that.date = new Date(year, month - 1, 1);
 9         }
10         _that.showUI();
11         
12     });

向右(下一个月)的代码控制:

 1 rightDiv.addEventListener(‘click‘, function(event){
 2         var year = parseInt(_that.date.getFullYear()),
 3             month = parseInt(_that.date.getMonth());
 4         if(month === 11){
 5             _that.date = new Date(year + 1, 0, 1);
 6         }else{
 7             _that.date = new Date(year, month + 1, 1);
 8         }
 9         _that.showUI();
10     });

需要修改重绘的控制,以_addHeader()为例,判断DOM节点是否存在,如果存在移除DOM节点,重绘。

    var exist = document.getElementById(‘vczero_datediv‘);
    if(!!exist){
        this.div.removeChild(exist);
    }

三、整个代码

整个简易日历已经可以使用了,上效果:

bubuko.com,布布扣

Calendar.js完整代码:

  1 /*
  2 +------------------------------
  3 @author:vczero
  4 @time:2014/8/10
  5 @desc:简易日历组件
  6 +------------------------------
  7 */
  8 var Calendar = (function(){
  9     var Calendar = function(div, date){
 10         this.div = document.getElementById(div);
 11         var w = this.div.style.width || 390;
 12         var h = this.div.style.height || (300 - 30);
 13         this.width = parseInt(w) >= 360 ? w : 360; 
 14         this.height = parseInt(h) >= 180 ? h : 180;
 15         this.date = date;
 16         this.div.style.width = this.width + ‘px‘; //按默认值设置回去
 17         this.div.style.height = this.height + ‘px‘;//按默认值设置回去
 18     };
 19 
 20     Calendar.week = [‘星期一‘, ‘星期二‘,‘星期三‘, ‘星期四‘,‘星期五‘, ‘星期六‘, ‘星期日‘];
 21 
 22     Calendar.prototype.getDate = null;
 23 
 24     Calendar.prototype.showUI = function(){
 25         var exist = document.getElementById(‘vczero_celldom_0‘);
 26         //如果存在节点:移除
 27         if(!!exist){
 28             for(var e = 0; e < 35; e++){
 29                 var node = document.getElementById(‘vczero_celldom_‘ + e);
 30                 this.div.removeChild(node);
 31             }
 32         }
 33 
 34         var width = this.width,
 35             height = this.height,
 36             cell = {width: (parseInt(width) - 20)/7, height: (parseInt(height) -30 - 20)/5},
 37             monthArr = this._monthPanel(this.date);
 38         this.div.style.paddingLeft = ‘8px‘; 
 39         this.div.style.border = ‘2px solid #57ABFF‘;
 40         this.div.style.cursor = ‘default‘;
 41         this.div.style.fontFamily = ‘微软雅黑‘;
 42         this._addHeader();
 43         this._addWeekday();
 44         for(var i = 0; i < 35; i++){
 45             var cellDOM = document.createElement(‘div‘);
 46             cellDOM.style.width = cell.width + ‘px‘;
 47             cellDOM.style.height = cell.height + ‘px‘;
 48             cellDOM.style.display = ‘inline-block‘;
 49             cellDOM.style.float = ‘left‘;
 50             cellDOM.style.cursor = ‘pointer‘;
 51             cellDOM.style.textAlign = ‘center‘;
 52             cellDOM.id = ‘vczero_celldom_‘ + i;
 53             cellDOM.style.lineHeight = cell.height + ‘px‘;
 54             cellDOM.setAttribute(‘date‘,monthArr[i]); //设置日期对象到DOM属性date上
 55             cellDOM.innerHTML = monthArr[i].getDate();
 56             //去掉最后一行横线
 57             if(i < 28){
 58                 cellDOM.style.borderBottom = ‘1px solid #C8CACC‘;
 59             }
 60             
 61             cellDOM.addEventListener(‘click‘, this.getDate);
 62             this.div.appendChild(cellDOM);
 63         }
 64         
 65     };
 66 
 67 
 68     Calendar.prototype._addHeader = function(){
 69         var exist = document.getElementById(‘vczero_datediv‘);
 70         if(!!exist){
 71             this.div.removeChild(exist);
 72         }
 73 
 74         var header = document.createElement(‘div‘);
 75         header.style.height = ‘22px‘;
 76         header.style.width = this.div.style.width || ‘800px‘;
 77 
 78         //包含左 时间 右的大DIV
 79         var dateDiv = document.createElement(‘div‘);
 80         dateDiv.style.width = ‘200px‘;
 81         dateDiv.style.height = ‘22px‘;
 82         dateDiv.style.margin = ‘0 auto‘;
 83         dateDiv.style.textAlign = ‘center‘;
 84         dateDiv.style.fontWeight = ‘bold‘;
 85         dateDiv.id = ‘vczero_datediv‘
 86 
 87         //< DIV
 88         var leftDiv = document.createElement(‘div‘);
 89         leftDiv.innerHTML = ‘<‘;
 90         leftDiv.style.display = ‘inline-block‘;
 91         leftDiv.style.float = ‘left‘;
 92         leftDiv.style.width = ‘50px‘;
 93         leftDiv.style.cursor = ‘pointer‘;
 94         leftDiv.style.color = ‘#C5BFBF‘;
 95         var _that = this; //获取到this对象
 96         leftDiv.addEventListener(‘click‘, function(event){
 97             var year = parseInt(_that.date.getFullYear()),
 98                 month = parseInt(_that.date.getMonth());
 99             if(month === 0){
100                 _that.date = new Date(year - 1, 11, 1);
101             }else{
102                 _that.date = new Date(year, month - 1, 1);
103             }
104             _that.showUI();
105             
106         });
107 
108         //> DIV
109         var rightDiv = document.createElement(‘div‘);
110         rightDiv.innerHTML = ‘>‘;
111         rightDiv.style.display = ‘inline-block‘;
112         rightDiv.style.float = ‘left‘;
113         rightDiv.style.width = ‘50px‘;
114         rightDiv.style.cursor = ‘pointer‘;
115         rightDiv.style.color = ‘#C5BFBF‘;
116         rightDiv.addEventListener(‘click‘, function(event){
117             var year = parseInt(_that.date.getFullYear()),
118                 month = parseInt(_that.date.getMonth());
119             if(month === 11){
120                 _that.date = new Date(year + 1, 0, 1);
121             }else{
122                 _that.date = new Date(year, month + 1, 1);
123             }
124             _that.showUI();
125         });
126 
127 
128         //显示月份的DIV
129         var timeDiv = document.createElement(‘div‘);
130         timeDiv.style.display = ‘inline-block‘;
131         timeDiv.style.float = ‘left‘;
132         timeDiv.style.width = ‘100px‘;
133         timeDiv.innerHTML = this.date.getFullYear() + ‘年‘ + (this.date.getMonth() + 1) + ‘月‘;
134 
135         dateDiv.appendChild(leftDiv);
136         dateDiv.appendChild(timeDiv);
137         dateDiv.appendChild(rightDiv);
138 
139         this.div.appendChild(dateDiv);
140     }
141 
142     //增加星期
143     Calendar.prototype._addWeekday = function(){
144         var exist = document.getElementById(‘vczero_week_0‘);
145         if(!!exist){
146             for(var i = 0; i < 7; i++){
147                 var node = document.getElementById(‘vczero_week_‘ + i);
148                 this.div.removeChild(node);
149             }
150             
151         }
152 
153         for(var i = 0; i < 7; i++){
154             var weekday = document.createElement(‘div‘);
155             weekday.style.width = (parseInt(this.width) - 20)/7 + ‘px‘;
156             weekday.style.height = ‘20px‘;
157             weekday.style.display = ‘inline-block‘;
158             weekday.style.float = ‘left‘;
159             weekday.style.color = ‘#BFBFBF‘;
160             weekday.style.fontWeight = ‘bold‘;
161             weekday.style.textAlign = ‘center‘;
162             weekday.id = ‘vczero_week_‘ + i;
163             weekday.innerHTML = Calendar.week[i];
164             this.div.appendChild(weekday);
165         }
166     }
167 
168     Calendar.prototype._monthPanel = function(date){
169         //如果传递了Date对象,则按Date对象进行计算月份面板
170         //否则,按照当前月份计算面板
171         var date = date || new Date(),
172             year = date.getFullYear(),
173             month = date.getMonth(),
174             day = date.getDate(),
175             week = date.getDay(),
176             currentDays = new Date(year, month + 1, 0).getDate(),
177             preDays = new Date(year, month, 0).getDate(),
178             firstDay = new Date(year, month, 1),
179             firstCell = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1,
180             bottomCell =  35 - currentDays - firstCell;
181         //前一个月该显示多少天
182         var preMonth = [];
183         for(var p = firstCell; p > 0; p--){
184             preMonth.push(new Date(year, month - 1, preDays - p + 1));
185         }
186         //本月
187         var currentMonth = [];
188         for(var c = 0; c < currentDays; c++){
189             currentMonth.push(new Date(year, month, c + 1));
190         }
191         //下一个月
192         var nextMonth = [];
193         for(var n = 0; n < bottomCell; n++){
194             nextMonth.push(new Date(year, month + 1, n + 1));
195         }
196 
197         preMonth = preMonth.concat(currentMonth, nextMonth);
198         return preMonth;
199     };
200 
201     return Calendar;
202 
203 })();

测试的HTML代码:

 1 <!doctype html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <script type="text/javascript" src="calendar.js"></script>
 6         <script type="text/javascript">
 7             function showCalendar(){
 8                 var c = new Calendar(calendar,new Date());
 9                 c.getDate = function(event){
10                     alert(new Date(this.getAttribute(date)).toLocaleString());
11                 };
12                 c.showUI();
13             }
14         </script>
15     </head>
16     <body onload="showCalendar()">
17         <div id="calendar" style="width:390px; height:270px;"></div>
18     </body>
19 </html>

github:https://github.com/vczero/myUI

下一篇:修复bug和兼容性测试。

 

javascript动手写日历组件(2)——优化UI和添加交互(by vczero),布布扣,bubuko.com

javascript动手写日历组件(2)——优化UI和添加交互(by vczero)

标签:des   style   blog   http   color   java   使用   io   

原文地址:http://www.cnblogs.com/vczero/p/js_ui_2.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!