想要实现的效果
点击日期选择框出现日历
有个日期控制栏帮助选择日期, 包括年、月、日的选择和今天
日历格子,初次点击日期选择框时显示此刻的日期,日历格子的日期应该包括这个月的所有天数,同时如果当月的1号不是周日,还应补全从周日到1号的天数。还要在这个月最后1号的后面补全到周六。
日期控制栏和日历格子的日期还有选择框里的日期的变化要是同步的。
实现思路
为了组件的可复用性,需要用面向对象的思想。
每个日历组件都是一个日历对象,主要包括日期选择框,日期控制显示栏,还有日历格子,为了保持日期控制显示栏和日历格子日期同步变化,日期控制栏和日历里面的每个格子都应该包含一个Date属性,点击日历里的格子,将格子存的Date属性作为函数参数,调用函数改变日期控制栏显示的时间。同理,日期控制栏时间变化时,也将Date属性作为参数调用函数,函数重新绘制日历格子。
上码:
function Calendar(parentId) { this.parentElement = document.getElementById(parentId); this.init(); } Calendar.prototype = { init: function() { this.contains = document.createElement("div"); this.contains.onselectstart = function(){return false}; //让按钮点击时不会出现文字被选中的蓝色块 this.dateInput = document.createElement("input"); this.datePicker = document.createElement("div"); this.showDateBar = document.createElement("div"); this.dateBox = document.createElement("div"); this.icon = document.createElement("i"); this.contains.className = 'datepicker-container'; this.dateInput.className = 'date-input'; this.dateInput.readOnly = true; var parent = this; this.dateInput.onclick = function(event){ parent.onDateInputClick(event); //点击日期选择框时显示日历格子 }; this.contains.onblur = function(){ parent.datePicker.style.display = 'none'; } this.datePicker.className = 'date-picker'; this.datePicker.style.display = 'none'; this.showDateBar.className = 'show-date'; this.dateBox.className = 'date-box'; this.icon.className = 'date-icon'; this.icon.innerHTML = ''; //iconfont这里用的阿里图标,可以自行替换 this.datePicker.appendChild(this.showDateBar); this.datePicker.appendChild(this.dateBox); this.contains.appendChild(this.dateInput); this.contains.appendChild(this.icon); this.contains.appendChild(this.datePicker); this.parentElement.appendChild(this.contains); }, }
初始化日期控制栏:
drawShowDateBar: function(parentElement){ var parent = this; var nowDate = new Date(); parentElement.date = nowDate; var nowYear = nowDate.getFullYear(); var nowMonth = nowDate.getMonth(); var nowDay = nowDate.getDate(); //showDateBar内容拼接 var contentStr ='<div><span>'+nowYear+'年</span><i></i><ul>'; for(var i=0;i<150;i++){ contentStr+='<li>'+(i+1900)+'年</li>'; } contentStr+='</ul></div>' +'<div><i></i><select>' for(var i=0;i<12;i++){ contentStr+='<option>'+(i+1)+'月</option>'; } contentStr+='</select><i></i></div>' +'<div><i></i><select></select>' +'<i></i></div>' +'<button>今天</button>' +'<div>'; var weekday = ['日', '一', '二', '三', '四', '五', '六']; for (var i = 0; i < 7; i++) { contentStr+='<span>'+weekday[i]+'</span>'; } contentStr+='</div>'; parentElement.innerHTML = contentStr; this.changeShowDateBar(nowDate); //插入到showTimeBar之后,初始化,传入的参数是现在的时间 var yearInput = parentElement.firstChild; //年选择框点击显示和隐藏选择列表 yearInput.onclick = function(){ //target和this的区别 target是触发事件的元素,this是处理事件的元素 var ul = this.lastChild; ul.style.display==='none'||ul.style.display==='none'? ul.style.display='inline-block':ul.style.display='none'; }; //为年选择下拉框绑定点击事件 var yearSelectBox = yearInput.lastChild; var yearLi = yearSelectBox.children; for(var i=0;i<yearLi.length;i++){ yearLi[i].onclick = function(){ parent.showDateBar.date.setFullYear(this.innerText.slice(0,-1)); parent.changeShowDateBar(parent.showDateBar.date); //时间改变之后都要重新调用,因为不同年,不同月,某个月的天数不全一样 }; } //为month的前后按钮添加点击事件 var monthInput = yearInput.nextSibling; monthInput.firstChild.onclick = function(){ var monthOptions = this.nextSibling; if(monthOptions.selectedIndex>0){ parent.showDateBar.date.setMonth(--monthOptions.selectedIndex); }else{ monthOptions.selectedIndex = 11; parent.showDateBar.date.setFullYear(parent.showDateBar.date.getFullYear()-1); parent.showDateBar.date.setMonth(11); } parent.changeShowDateBar(parent.showDateBar.date); }; monthInput.lastChild.onclick = function(){ var monthOptions = this.previousSibling; if(monthOptions.selectedIndex<11){ parent.showDateBar.date.setMonth(++monthOptions.selectedIndex); }else{ monthOptions.selectedIndex = 0; parent.showDateBar.date.setFullYear(parent.showDateBar.date.getFullYear()+1); parent.showDateBar.date.setMonth(0); } parent.changeShowDateBar(parent.showDateBar.date); } monthInput.children[1].onchange = function(){ parent.showDateBar.date.setMonth(this.selectedIndex); parent.changeShowDateBar(parent.showDateBar.date) }; //为day的前后按钮添加点击事件 var dayInput = monthInput.nextSibling; dayInput.firstChild.onclick = function(){ var dayOptions = this.nextSibling; if(dayOptions.selectedIndex>0){ parent.showDateBar.date.setDate(dayOptions.selectedIndex--); }else{ parent.showDateBar.date.setMonth(parent.showDateBar.date.getMonth()-1); parent.showDateBar.date.setDate(parent.getDaysOfMonth(parent.showDateBar.date)); } parent.changeShowDateBar(parent.showDateBar.date); }; dayInput.lastChild.onclick = function(){ var dayOptions = this.previousSibling; if(dayOptions.selectedIndex < dayOptions.length-1){ dayOptions.selectedIndex++; parent.showDateBar.date.setDate(dayOptions.selectedIndex+1); }else{ parent.showDateBar.date.setDate(1); parent.showDateBar.date.setMonth(parent.showDateBar.date.getMonth()+1); } parent.changeShowDateBar(parent.showDateBar.date); }; dayInput.children[1].onchange = function(){ parent.showDateBar.date.setDate(this.selectedIndex+1); parent.changeShowDateBar(parent.showDateBar.date) }; //为今天按钮绑定点击事件 var todayBtn = dayInput.nextSibling; todayBtn.onclick = function(){ parent.drawPicker(new Date()); parent.changeShowDateBar(new Date()); } },
drawShowDateBar函数为日期控制栏的年份、月份、和天的点击按钮设置了点击事件处理函数。还有选择下拉框变化的处理函数。