JS制作简单的日历控件【JS Date对象操作实例演示】
2012-06-24 22:36 VVG 阅读(18718) 评论(13) 编辑 收藏 举报JS制作简单的日历控件【JS Date对象操作实例】
一直对JS 中的Date 对象不是很熟练,缺乏操作实践,端午节抽空复习了一下,做了一个简单的日期选择控件
日历外观参考了淘宝旅行中的日期控件,控件只有基本功能,木有做节日显示:
2012年7月14日 增加了IE6的selectBUG,遮挡问题,修改了两个日历能够同时出现的问题。
使用方法:
只需传入日期INPUT元素的ID即可,isSelect选项为是否为SELECT下拉选择年月设置
var myDate1 = new Calender({id:\'j_Date1\'}); var myDate2 = new Calender({id:\'j_Date2\',isSelect:!0});
演示如下:
日历组件示例
支持选择年月 支持SELECT选择年月
有兴趣的看源代码吧,详细源代码+注释如下:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>日历组件示例</title> <style> .calendar{font-family:Tahoma; background:#fff; float:left; border-style:solid; border-width:1px; border-color:#85BEE5 #3485C0 #3485C0 #85BEE5; position:relative; padding:10px; } .calendar dl,.calendar dd{margin:0; padding:0; width:183px; font-size:12px; line-height:22px;} .calendar dt.title-date{ display:block; border-bottom:1px solid #E4E4E4; font-weight:700; position:relative; margin-bottom:5px; padding-bottom:3px;} .calendar dt{ float:left; width:25px; margin-left:1px; text-align:center;} .calendar dt.title-date{ width:100%;} .calendar dd{clear: both;width: 183px;height: 139px;font-weight: 700;background:url(http://images.cnblogs.com/likecs_com/NNUF/379856/o_bg.png) no-repeat; margin:0;} .prevyear,.nextyear, .prevmonth,.nextmonth{cursor:pointer;height:9px; background:url(http://images.cnblogs.com/likecs_com/NNUF/379856/o_nextprv.png) no-repeat; overflow:hidden;position:absolute; top:8px; text-indent:-999px;} .prevyear{ left:4px; width:9px;} .prevmonth{ width:5px; background-position:-9px 0; left:20px;} .nextyear{ width:9px; background-position:-19px 0; right:5px;} .nextmonth{ width:5px; background-position:-14px 0; right:20px;} .calendar dd a{float: left;width: 25px;height: 22px; color:blue; overflow: hidden; text-decoration: none; margin: 1px 0 0 1px; text-align:center;} .calendar dd a.disabled{color:#999;} .calendar dd a.tody{ color:red; } .calendar dd a.on{background:blue; color:#fff;} .calendar dd a.live{cursor:pointer} .input{ border:1px solid #ccc; padding:4px; background:url(http://images.cnblogs.com/likecs_com/NNUF/379856/o_nextprv.png) no-repeat right -18px;} </style> </head> <body> <br/> <br/> <h3>支持选择年月 支持SELECT选择年月</h3> <div><input type="text" id="j_Date1" class="input"> <input type="text" id="j_Date2" class="input"></div> <br/> <select name="IE6" > <option>测试IE6</option> <option>2</option> <option>3</option> </select> <select name="IE6" > <option>测试IE6</option> <option>2</option> <option>3</option> </select> <select name="IE6"> <option>测试IE6</option> <option>2</option> <option>3</option> </select> <select name="IE6" > <option>测试IE6</option> <option>2</option> <option>3</option> </select> <select name="IE6" > <option>测试IE6</option> <option>2</option> <option>3</option> </select> <select name="IE6"> <option>测试IE6</option> <option>2</option> <option>3</option> </select> <div></div> <!--日历控件JS源码--> <script> /** * @namespace _CalF * 日历控件所用便捷函数 * */ _CalF = { // 选择元素 $:function(arg,context){ var tagAll,n,eles=[],i,sub = arg.substring(1); context = context||document; if(typeof arg ==\'string\'){ switch(arg.charAt(0)){ case \'#\': return document.getElementById(sub); break; case \'.\': if(context.getElementsByClassName) return context.getElementsByClassName(sub); tagAll = _CalF.$(\'*\',context); n = tagAll.length; for(i = 0;i<n;i++){ if(tagAll[i].className.indexOf(sub) > -1) eles.push(tagAll[i]); } return eles; break; default: return context.getElementsByTagName(arg); break; } } }, // 绑定事件 bind:function(node,type,handler){ node.addEventListener?node.addEventListener(type, handler, false):node.attachEvent(\'on\'+ type, handler); }, // 获取元素位置 getPos:function (node) { var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft, scrollt = document.documentElement.scrollTop || document.body.scrollTop; pos = node.getBoundingClientRect(); return {top:pos.top + scrollt, right:pos.right + scrollx, bottom:pos.bottom + scrollt, left:pos.left + scrollx } }, // 添加样式名 addClass:function(c,node){ node.className = node.className + \' \' + c; }, // 移除样式名 removeClass:function(c,node){ var reg = new RegExp("(^|\\s+)" + c + "(\\s+|$)","g"); node.className = node.className.replace(reg, \'\'); }, // 阻止冒泡 stopPropagation:function(event){ event = event || window.event; event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; } }; /** * @name Calender * @constructor * @created by VVG * @http://www.cnblogs.com/NNUF/ * @mysheller@163.com * */ function Calender() { this.initialize.apply(this, arguments); } Calender.prototype = { constructor:Calender, // 模板数组 _template :[ \'<dl>\', \'<dt class="title-date">\', \'<span class="prevyear">prevyear</span><span class="prevmonth">prevmonth</span>\', \'<span class="nextyear">nextyear</span><span class="nextmonth">nextmonth</span>\', \'</dt>\', \'<dt><strong>日</strong></dt>\', \'<dt>一</dt>\', \'<dt>二</dt>\', \'<dt>三</dt>\', \'<dt>四</dt>\', \'<dt>五</dt>\', \'<dt><strong>六</strong></dt>\', \'<dd></dd>\', \'</dl>\'], // 初始化对象 initialize :function (options) { this.id = options.id; // input的ID this.input = _CalF.$(\'#\'+ this.id); // 获取INPUT元素 this.isSelect = options.isSelect; // 是否支持下拉SELECT选择年月,默认不显示 this.inputEvent(); // input的事件绑定,获取焦点事件 }, // 创建日期最外层盒子,并设置盒子的绝对定位 createContainer:function(){ // 如果存在,则移除整个日期层Container var odiv = _CalF.$(\'#\'+ this.id + \'-date\'); if(!!odiv) odiv.parentNode.removeChild(odiv); var container = this.container = document.createElement(\'div\'); container.id = this.id + \'-date\'; container.style.position = "absolute"; container.zIndex = 999; // 获取input表单位置inputPos var input = _CalF.$(\'#\' + this.id), inputPos = _CalF.getPos(input); // 根据input的位置设置container高度 container.style.left = inputPos.left + \'px\'; container.style.top = inputPos.bottom - 1 + \'px\'; // 设置日期层上的单击事件,仅供阻止冒泡,用途在日期层外单击关闭日期层 _CalF.bind(container, \'click\', _CalF.stopPropagation); document.body.appendChild(container); }, // 渲染日期 drawDate:function (odate) { // 参数 odate 为日期对象格式 var dateWarp, titleDate, dd, year, month, date, days, weekStart,i,l,ddHtml=[],textNode; var nowDate = new Date(),nowyear = nowDate.getFullYear(),nowmonth = nowDate.getMonth(), nowdate = nowDate.getDate(); this.dateWarp = dateWarp = document.createElement(\'div\'); dateWarp.className = \'calendar\'; dateWarp.innerHTML = this._template.join(\'\'); this.year = year = odate.getFullYear(); this.month = month = odate.getMonth()+1; this.date = date = odate.getDate(); this.titleDate = titleDate = _CalF.$(\'.title-date\', dateWarp)[0]; // 是否显示SELECT if(this.isSelect){ var selectHtmls =[]; selectHtmls.push(\'<select>\'); for(i = 2020;i>1970;i--){ if(i != this.year){ selectHtmls.push(\'<option value ="\'+ i +\'">\'+ i +\'</option>\'); }else{ selectHtmls.push(\'<option value ="\'+ i +\'" selected>\'+ i +\'</option>\'); } } selectHtmls.push(\'</select>\'); selectHtmls.push(\'年\'); selectHtmls.push(\'<select>\'); for(i = 1;i<13;i++){ if(i != this.month){ selectHtmls.push(\'<option value ="\'+ i +\'">\'+ i +\'</option>\'); }else{ selectHtmls.push(\'<option value ="\'+ i +\'" selected>\'+ i +\'</option>\'); } } selectHtmls.push(\'</select>\'); selectHtmls.push(\'月\'); titleDate.innerHTML = selectHtmls.join(\'\'); // 绑定change事件 this.selectChange(); }else{ textNode = document.createTextNode(year + \'年\' + month + \'月\'); titleDate.appendChild(textNode); this.btnEvent(); } // 获取模板中唯一的DD元素 this.dd = dd = _CalF.$(\'dd\',dateWarp)[0]; // 获取本月天数 days = new Date(year, month, 0).getDate(); // 获取本月第一天是星期几 weekStart = new Date(year, month-1,1).getDay(); // 开头显示空白段 for (i = 0; i < weekStart; i++) { ddHtml.push(\'<a> </a>\'); } // 循环显示日期 for (i = 1; i <= days; i++) { if (year < nowyear) { ddHtml.push(\'<a class="live disabled">\' + i + \'</a>\'); } else if (year == nowyear) { if (month < nowmonth + 1) { ddHtml.push(\'<a class="live disabled">\' + i + \'</a>\'); } else if (month == nowmonth + 1) { if (i < nowdate) ddHtml.push(\'<a class="live disabled">\' + i + \'</a>\'); if (i == nowdate) ddHtml.push(\'<a class="live tody">\' + i + \'</a>\'); if (i > nowdate) ddHtml.push(\'<a class="live">\' + i + \'</a>\'); } else if (month > nowmonth + 1) { ddHtml.push(\'<a class="live">\' + i + \'</a>\'); } } else if (year > nowyear) { ddHtml.push(\'<a class="live">\' + i + \'</a>\'); } } dd.innerHTML = ddHtml.join(\'\'); // 如果存在,则先移除 this.removeDate(); // 添加 this.container.appendChild(dateWarp); //IE6 select遮罩 var ie6 = !!window.ActiveXObject && !window.XMLHttpRequest; if(ie6) dateWarp.appendChild(this.createIframe()); // A link事件绑定 this.linkOn(); // 区域外事件绑定 this.outClick(); }, createIframe:function(){ var myIframe = document.createElement(\'iframe\'); myIframe.src = \'about:blank\'; myIframe.style.position = \'absolute\'; myIframe.style.zIndex = \'-1\'; myIframe.style.left = \'-1px\'; myIframe.style.top = 0; myIframe.style.border = 0; myIframe.style.filter = \'alpha(opacity= 0 )\'; myIframe.style.width = this.container.offsetWidth + \'px\'; myIframe.style.height = this.container.offsetHeight + \'px\'; return myIframe; }, // SELECT CHANGE 事件 selectChange:function(){ var selects,yearSelect,monthSelect,that = this; selects = _CalF.$(\'select\',this.titleDate); yearSelect = selects[0]; monthSelect = selects[1]; _CalF.bind(yearSelect, \'change\',function(){ var year = yearSelect.value; var month = monthSelect.value; that.drawDate(new Date(year, month-1, that.date)); }); _CalF.bind(monthSelect, \'change\',function(){ var year = yearSelect.value; var month = monthSelect.value; that.drawDate(new Date(year, month-1, that.date)); }) }, // 移除日期DIV.calendar removeDate:function(){ var odiv = _CalF.$(\'.calendar\',this.container)[0]; if(!!odiv) this.container.removeChild(odiv); }, // 上一月,下一月按钮事件 btnEvent:function(){ var prevyear = _CalF.$(\'.prevyear\',this.dateWarp)[0], prevmonth = _CalF.$(\'.prevmonth\',this.dateWarp)[0], nextyear = _CalF.$(\'.nextyear\',this.dateWarp)[0], nextmonth = _CalF.$(\'.nextmonth\',this.dateWarp)[0], that = this; prevyear.onclick = function(){ var idate = new Date(that.year-1, that.month-1, that.date); that.drawDate(idate); }; prevmonth.onclick = function(){ var idate = new Date(that.year, that.month-2,that.date); that.drawDate(idate); }; nextyear.onclick = function(){ var idate = new Date(that.year + 1,that.month - 1, that.date); that.drawDate(idate); }; nextmonth.onclick = function(){ var idate = new Date(that.year , that.month, that.date); that.drawDate(idate); } }, // A 的事件 linkOn:function(){ var links = _CalF.$(\'.live\',this.dd),i,l=links.length,that=this; for(i = 0;i<l;i++){ links[i].index = i; links[i].onmouseover = function(){ _CalF.addClass("on",links[this.index]); }; links[i].onmouseout = function(){ _CalF.removeClass("on",links[this.index]); }; links[i].onclick = function(){ that.date = this.innerHTML; that.input.value = that.year + \'-\' + that.month + \'-\' + that.date; that.removeDate(); } } }, // 表单的事件 inputEvent:function(){ var that = this; _CalF.bind(this.input, \'focus\',function(){ that.createContainer(); that.drawDate(new Date()); }); }, // 鼠标在对象区域外点击,移除日期层 outClick:function(){ var that = this; _CalF.bind(document, \'click\',function(event){ event = event || window.event; var target = event.target || event.srcElement; if(target == that.input)return; that.removeDate(); }) } }; var myDate1 = new Calender({id:\'j_Date1\'}); var myDate2 = new Calender({id:\'j_Date2\',isSelect:!0}); </script> </body> </html>
转载请注明出处:http://www.cnblogs.com/NNUF/