一、列表
Javascript动手写日历组件的文章列表,主要是通过原生的JavaScript写的一个简约的日历组件:
(1)javascript动手写日历组件(1)——构建日历逻辑:http://www.cnblogs.com/vczero/p/js_ui_1.html
(2)javascript动手写日历组件(2)——优化UI和添加交互:http://www.cnblogs.com/vczero/p/js_ui_2.html
(3)javascript动手写日历组件(2)——内存和性能优化:http://www.cnblogs.com/vczero/p/js_ui_3.html
(4)github:https://github.com/vczero/UI
日历虽然很简约,但是作为基本使用可以满足要求,UI也相对清爽。
在线Demo:http://vczero.github.io/ui/calendar.html
二、内存和性能优化
(1)手动移除事件处理程序
以为在DOM重绘的过程中,避免事件处理程序驻留内存,因此,手动XXX.onclik = null;
for(var e = 0; e < 35; e++){ var node = document.getElementById('vczero_celldom_' + e); node.onclick = null; //移除事件处理程序 this.div.removeChild(node); }
if(!!exist){ exist.onclick = null; this.div.removeChild(exist); }
(2)将绑定事件处理程序改成事件委托
对于事件处理程序过多的问题,使用委托是最好的方式。事件委托实际上是事件冒泡,可以在父节点添加事件处理程序,然后,根据需要的目标节点,执行代码。具体的代码改进如下,将for循环中的事件绑定改为在this.div(父元素)上的事件委托:
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.CSSFloat = 'left'; 7 cellDOM.style.cursor = 'pointer'; 8 cellDOM.style.textAlign = 'center'; 9 cellDOM.id = 'vczero_celldom_' + i;10 cellDOM.style.lineHeight = cell.height + 'px';11 cellDOM.setAttribute('date',monthArr.date[i]); //设置日期对象到DOM属性date上12 cellDOM.innerHTML = monthArr.date[i].getDate();13 //去掉最后一行横线14 if(i < 28){15 cellDOM.style.borderBottom = '1px solid #C8CACC';16 }17 18 if(i < monthArr.PReLen || i >= monthArr.currentLen + monthArr.preLen){19 cellDOM.style.color = '#BFBFBF';20 }21 this.div.appendChild(cellDOM);22 }23 24 var _that = this;25 //使用父元素事件委托26 this.div.addEventListener('click',function(e){27 var node = e.target;28 if(node.id.indexOf('vczero_celldom_') > -1){29 var date = new Date(node.getAttribute('date')).toLocaleString();30 callback(date);31 }32 });
(3)本次修改还包括:
==>前一个月和下一个的日期变灰,本月黑色。
==>将,showUI函数改为回调,可以在调用时更为方便。
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.showUI(function(date){10 console.log(date);11 });12 }13 </script>14 </head>15 <body onload="showCalendar()">16 <div id="calendar" style="width:390px; height:270px;"></div>17 </body>18 </html>
(4)整个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['showUI'] = function(callback){ 23 var exist = document.getElementById('vczero_celldom_0'); 24 //如果存在节点:移除 25 if(!!exist){ 26 for(var e = 0; e < 35; e++){ 27 var node = document.getElementById('vczero_celldom_' + e); 28 node.onclick = null; //移除事件处理程序 29 this.div.removeChild(node); 30 } 31 } 32 33 var width = this.width, 34 height = this.height, 35 cell = {width: (parseInt(width) - 20)/7, height: (parseInt(height) -30 - 20)/5}, 36 monthArr = this._monthPanel(this.date); 37 this.div.style.paddingLeft = '8px'; 38 this.div.style.border = '2px solid #57ABFF'; 39 this.div.style.cursor = 'default'; 40 this.div.style.fontFamily = '微软雅黑'; 41 this._addHeader(); 42 this._addWeekday(); 43 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.cssFloat = '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.date[i]); //设置日期对象到DOM属性date上 55 cellDOM.innerHTML = monthArr.date[i].getDate(); 56 //去掉最后一行横线 57 if(i < 28){ 58 cellDOM.style.borderBottom = '1px solid #C8CACC'; 59 } 60 61 if(i < monthArr.preLen || i >= monthArr.currentLen + monthArr.preLen){ 62 cellDOM.style.color = '#BFBFBF'; 63 } 64 this.div.appendChild(cellDOM); 65 } 66 67 var _that = this; 68 //使用父元素事件委托 69 this.div.addEventListener('click',function(e){ 70 var node = e.target; 71 if(node.id.indexOf('vczero_celldom_') > -1){ 72 var date = new Date(node.getAttribute('date')).toLocaleString(); 73 callback(date); 74 } 75 }); 76 }; 77 78 Calendar.prototype._addHeader = function(){ 79 var exist = document.getElementById('vczero_datediv'); 80 if(!!exist){ 81 exist.onclick = null; 82 this.div.removeChild(exist); 83 } 84 85 var header = document.createElement('div'); 86 header.style.height = '22px'; 87 header.style.width = this.div.style.width || '800px'; 88 89 //包含左 时间 右的大DIV 90 var dateDiv = document.createElement('div'); 91 dateDiv.style.width = '200px'; 92 dateDiv.style.height = '22px'; 93 dateDiv.style.margin = '0 auto'; 94 dateDiv.style.textAlign = 'center'; 95 dateDiv.style.fontWeight = 'bold'; 96 dateDiv.id = 'vczero_datediv' 97 98 //< DIV 99 var leftDiv = document.createElement('div');100 leftDiv.innerHTML = '<';101 leftDiv.style.display = 'inline-block';102 leftDiv.style.float = 'left';103 leftDiv.style.width = '50px';104 leftDiv.style.cursor = 'pointer';105 leftDiv.style.color = '#C5BFBF';106 var _that = this; //获取到this对象107 leftDiv.addEventListener('click', function(event){108 var year = parseInt(_that.date.getFullY
新闻热点
疑难解答