首页 > 网站 > WEB开发 > 正文

javascript动手写日历组件(3)——内存和性能优化(by vczero)

2024-04-27 14:20:26
字体:
来源:转载
供稿:网友

javascript动手写日历组件(3)——内存和性能优化(by vczero)

一、列表

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
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表