时间一晃就是一年啊。 记得第一次写的日历,到第二次改进用了二年。 这次改进又用了一年。。
时间总是这样悄然流走,而自己却还在原地踏步。。不禁有点悲伤
这次改进也不大 就是用了iframe 使select或flash不再烦人的遮住日历
有很多朋友都和我讲怎么还不改进一下呢,我只能苦笑。我也想改进啊,但总有很多事情牵扯。。。
[演示] [下载]
有朋友讲 iframe里出错。 现修改了一个版本专门用于iframe里的
调用时创建
var cdr = new Calendar("cdr","top.frmMain"); 后个参数为frame的名称
[框架版下载]
/******************************************************************************************* * 创建对象 var c = new Calendar("c"); * 调用方法 c.show(arg1,arg2,arg3); * 参数1: 文本输入框(必填). 如 onfocus="c.show(this)"; * 参数2: 按钮或其它可用单击事件的HTML元素(如果使用按钮方式则必填). 如 onclick="c.show(this,$(*))" *=文本输入框名称 * 参数3: 如果没有文本框没有值则使用该值初始化日历(选填). 如 onfocus="c.show(this,'2006-01-01') * 注: 参数顺序不分先后. MSIE6/Opera8/FireFox1.5 下测试通过 * 2007-11-10 修正被Select元素遮挡问题 ************************如果您使用本日历控件 请保留该信息 谢谢! *************************** * http://2lin.net * Email:caoailin@gmail.com * QQ:38062022 * Creation date: 2007-11-10 *********************************************************************************************/ function Calendar(objName) { this.style = { borderColor : "#909eff", //边框颜色 headerBackColor : "#909EFF", //表头背景颜色 headerFontColor : "#ffffff", //表头字体颜色 bodyBarBackColor : "#f4f4f4", //日历标题背景色 bodyBarFontColor : "#000000", //日历标题字体色 bodyBackColor : "#ffffff", //日历背景色 bodyFontColor : "#000000", //日历字体色 bodyHolidayFontColor : "#ff0000", //假日字体色 watermarkColor : "#d4d4d4", //背景水印色 moreDayColor : "#cccccc" }; this.showMoreDay = false; //是否显示上月和下月的日期 this.dateFormat = 'yyyy-mm-dd'; this.Obj = objName; this.date = null; this.mouseOffset = null; this.dateInput = null; this.timer = null; this.z_index = 20071111; this.Create(); }; Calendar.prototype.toString = function() { var str = this.getStyle(); str += '<div Author="alin" class="calendar" style="display:none;" onselectstart="return false" oncontextmenu="return false" id="inCalendar">\n'; str += '<div Author="alin" class="cdrWatermark" id="cdrWatermark"></div><div id="cdrBody" style="position:absolute;left:0px;top:0px;z-index:2;width:140px;">'; str += this.getHeader(); str += this.getBody(); str += '</div><div Author="alin" id="cdrMenu" style="position:absolute;left:0px;top:0px;z-index:3;display:none;" onmouseover="top.' + this.Obj + '.showMenu(null);" onmouseout="top.' + this.Obj + '.hideMenu();"></div></div>'; return str; } Calendar.prototype.Create = function() { var fra = '<iframe id="Calendar" frameborder="0" scrolling="no" style="display:none;position:absolute;width:142px;height:200px;left:0px;top:0px;z-index:'+this.z_index+';"></iframe>'; document.write(fra); if($('Calendar').contentDocument) { $('Calendar').contentDocument.write(this); $('Calendar').contentDocument.close(); } else { $('Calendar').document.write(this); $('Calendar').document.close(); } }; Calendar.prototype.getStyle = function() { var str = '<style type="text/css">\n'; str += '.calendar{position:absolute;width:140px!important;width /**/:142px;height:184px!important;height /**/:174px;background-color:'+this.style.bodyBackColor+';border:1px solid ' + this.style.borderColor + ';left:0px;top:0px;z-index:'+this.z_index+';}\n'; str += '.cdrHeader{background-color:'+ this.style.headerBackColor +';width:140px;height:22px;font-size:12px;font-family:"宋体";color:'+this.style.headerFontColor+';}\n'; str += '.cdrWatermark{position:absolute;left:0px;top:55px;width:140px;font-family: Arial Black;font-size:50px;color:'+this.style.watermarkColor+';z-index:1;text-align:center;}\n'; str += '.cdrBodyBar{background-color:' + this.style.bodyBarBackColor + ';font-size:12px;font-family:"宋体";color:' + this.style.bodyBarFontColor + ';width:140px;height:20px;}\n'; str += '.cdrBody{width:140px;height:122px!important; height /**/:110px;font-size:12px;font-family:"宋体";cursor:pointer;color:' + this.style.bodyFontColor + ';}\n'; str += '.dayOver{height:16px;padding:0px;border:1px solid black;background-color:#f4f4f4;font-size:12px;font-family:"宋体";}\n'; str += '.dayOut{padding:1px;border:none;height:16px;font-size:12px;font-family:"宋体";}\n'; str += '.menuOver{background-color:'+this.style.headerBackColor+';color:'+this.style.headerFontColor+';font-size:12px;font-family:"宋体";}\n'; str += '.headerOver{border:1px solid black;background-color:#f4f4f4;color:black;cursor:default;font-size:12px;font-family:"宋体";}\n'; str += '.cdrMenu{font-size:12px;border:1px solid #000000;background-color:#ffffff;cursor:default;width:100%;font-size:12px;font-family:"宋体";}\n'; str += 'html>body #Calendar{width:142px;174px;font-size:12px;font-family:"宋体";}'; str += '</style>\n'; return str; }; Calendar.prototype.getHeader = function() { var str = '<table Author="alin" class="cdrHeader" cellSpacing="2" cellPadding="0"><tr Author="alin" align="center">\n'; str += '<td Author="alin" onmouseover="this.className=\'headerOver\'" onmouseout="this.className=\'\'" id="previousYear" title="上一年份" style="cursor:pointer;width:10px;" onclick="top.'+this.Obj+'.onChangeYear(false);"><<</td>\n'; str += '<td Author="alin" onmouseover="this.className=\'headerOver\'" onmouseout="this.className=\'\'" id="previousMonth" title="上一月份" style="cursor:pointer;width:10px;" onclick="top.'+this.Obj+'.onChangeMonth(false);"><</td>\n'; str += '<td Author="alin" onmouseover="this.className=\'headerOver\'" id="currentYear" style="width:50px;" onclick="top.' + this.Obj + '.showMenu(true);" onmouseout="top.' + this.Obj + '.hideMenu();this.className=\'\';">0</td>\n'; str += '<td Author="alin" onmouseover="this.className=\'headerOver\'" id="currentMonth" onclick="top.' + this.Obj + '.showMenu(false);" onmouseout="top.' + this.Obj + '.hideMenu();this.className=\'\';">0</td>\n'; str += '<td Author="alin" onmouseover="this.className=\'headerOver\'" onmouseout="this.className=\'\'" id="nextMonth" title="下一月份" style="cursor:pointer;width:10px;" onclick="top.'+this.Obj+'.onChangeMonth(true);">></td>\n'; str += '<td Author="alin" onmouseover="this.className=\'headerOver\'" onmouseout="this.className=\'\'" id="nextYear" title="下一年份" style="cursor:pointer;width:10px;" onclick="top.'+this.Obj+'.onChangeYear(true);">>></td></tr>\n'; str += '</table>\n'; return str; }; Calendar.prototype.getBody = function() { var n = 0; var str = this.getBodyBar(); str += '<table Author="alin" class="cdrBody" cellSpacing="2" cellPadding="0">\n'; for(i = 0; i < 6; i++) { str += '<tr Author="alin" align="center">'; for(j = 0; j < 7; j++) { str += '<td Author="alin" class="dayOut" id="cdrDay'+(n++)+'" width="13%"></td>\n'; } str += '</tr>'; } str += '</table>\n'; str += '<table Author="alin" class="cdrBodyBar" cellSpacing="2" cellPadding="0"><tr align="center" Author="alin"><td Author="alin" style="cursor:pointer;" onclick="top.'+this.Obj+'.getToday();">今天:'+new Date().toFormatString("yyyy年mm月dd日")+'</td></tr></table>\n'; return str; }; Calendar.prototype.getBodyBar = function() { var str = '<table Author="alin_bar" id="cdrBodyBar" class="cdrBodyBar" style="cursor:move;" cellSpacing="2" cellPadding="0"><tr Author="alin_bar" align="center">\n'; var day = new Array('日','一','二','三','四','五','六'); for(i = 0; i < 7; i++) { str += '<td Author="alin_bar">' + day[i] + '</td>\n'; } str += '</tr></table>'; return str; } Calendar.prototype.getYearMenu = function(year) { var str = '<table Author="alin" cellSpacing="0" class="cdrMenu" cellPadding="0">\n'; for(i = 0; i < 10; i++) { var _year = year + i; var _date = new Date(_year,this.date.getMonth(),this.date.getDate()); str += '<tr Author="alin" align="center"><td Author="alin" width="13%" height="16" '; if(this.date.getFullYear() != _year) { str += 'onmouseover="this.className=\'menuOver\'" onmouseout="this.className=\'\'" '; } else { str += 'class="menuOver"'; } str += 'onclick="top.' + this.Obj + '.bindDate(\'' + _date.toFormatString("-") + '\')">' + _year + '年</td>\n'; str += '</tr>'; } str += '<tr Author="alin" align="center"><td Author="alin"><table Author="alin" style="font-size:12px;width:100%;" cellSpacing="0" cellPadding="0">\n'; str += '<tr Author="alin" align="center"><td Author="alin" onmouseover="this.className=\'menuOver\'" onmouseout="this.className=\'\'" onclick="top.'+this.Obj+'.getYearMenu('+ (year - 10) + ')"><<</td>\n'; str += '<td Author="alin" onmouseover="this.className=\'menuOver\'" onmouseout="this.className=\'\'" onclick="top.'+this.Obj+'.getYearMenu('+ (year + 10) +')">>></td><tr>\n'; str += '</table></td></tr>\n'; str += '</table>'; var _menu = $F("cdrMenu"); _menu.innerHTML = str; }; Calendar.prototype.getMonthMenu = function() { var str = '<table Author="alin" cellSpacing="0" class="cdrMenu" cellPadding="0">\n'; for(i = 1; i <= 12; i++) { var _date = new Date(this.date.getFullYear(),i-1,this.date.getDate()); str += '<tr Author="alin" align="center"><td Author="alin" height="16" '; if(this.date.getMonth() + 1 != i) { str += 'onmouseover="this.className=\'menuOver\'" onmouseout="this.className=\'\'" '; } else { str += 'class="menuOver"'; } str += 'onclick="top.' + this.Obj + '.bindDate(\'' + _date.toFormatString("-") + '\')">'+addZero(i)+'月</td></tr>\n'; } str += '</table>'; var _menu = $F("cdrMenu"); _menu.innerHTML = str; }; Calendar.prototype.show = function() { if (arguments.length > 3 || arguments.length == 0) { alert("对不起!传入参数不对!" ); return; } var _date = null; var _evObj = null; var _initValue = null this.hide(); for(i = 0; i < arguments.length; i++) { if(typeof(arguments[i]) == "object" && arguments[i].type == "text") {_date = arguments[i];} else if(typeof(arguments[i]) == "object") {_evObj = arguments[i];} else if(typeof(arguments[i]) == "string") {_initValue = arguments[i];} } _evObj = _evObj || _date; inputObj = _date; targetObj = _evObj if(!_date){alert("传入参数错误!"); return;} this.dateInput = _date; _date = _date.value; if(_date == "" && _initValue) _date = _initValue; this.bindDate(_date); var _target = getPosition(_evObj); var _obj = $("Calendar"); if(_obj.contentDocument) _obj.style.height = '220px';// else _obj.style.height = '184px'; _obj.style.display = ""; _obj.style.left = _target.x + 'px'; if((document.body.clientHeight - (_target.y + _evObj.clientHeight)) >= _obj.clientHeight) { _obj.style.top = (_target.y + _evObj.clientHeight) + 'px'; } else { _obj.style.top = (_target.y - _obj.clientHeight) + 'px'; } _obj = $F("inCalendar"); _obj.style.display = ""; if($("Calendar").contentDocument) return; _obj.style.left = _target.x + 'px'; if((document.body.clientHeight - (_target.y + _evObj.clientHeight)) >= _obj.clientHeight) { _obj.style.top = (_target.y + _evObj.clientHeight) + 'px'; } else { _obj.style.top = (_target.y - _obj.clientHeight) + 'px'; } }; Calendar.prototype.hide = function() { $("Calendar").style.display = "none"; $F("inCalendar").style.display = "none"; }; Calendar.prototype.bindDate = function(date) { var _monthDays = new Array(31,30,31,30,31,30,31,31,30,31,30,31); var _arr = date.replace(/[^\d]/ig,'-').replace(/^\-|\-$/ig,'').split('-'); //alert(date.replace(/[^\d]/ig,'-').replace(/^\-|\-$/ig,'')); var _date = new Date(_arr[0],_arr[1]-1,_arr[2]); if(isNaN(_date)) _date = new Date(); this.date = _date; this.bindHeader(); var _year = _date.getFullYear(); var _month = _date.getMonth(); var _day = 1; var _startDay = new Date(_year,_month,1).getDay(); var _previYear = _month == 0 ? _year - 1 : _year; var _previMonth = _month == 0 ? 11 : _month - 1; var _previDay = _monthDays[_previMonth]; if (_previMonth == 1) _previDay =((_previYear%4==0)&&(_previYear%100!=0)||(_previYear%400==0))?29:28; _previDay -= _startDay - 1; var _nextDay = 1; _monthDays[1] = ((_year%4==0)&&(_year%100!=0)||(_year%400==0))?29:28; for(i = 0; i < 40; i++) { var _dayElement = $F("cdrDay" + i); _dayElement.onmouseover = Function(this.Obj + ".onMouseOver(this)"); _dayElement.onmouseout = Function(this.Obj + ".onMouseOut(this)"); _dayElement.onclick = Function(this.Obj + ".onClick(this)"); this.onMouseOut(_dayElement); _dayElement.style.color = ""; if(i < _startDay) { //获取上一个月的日期 if(this.showMoreDay) { var _previDate = new Date(_year,_month - 1,_previDay); _dayElement.innerHTML = _previDay; _dayElement.title = _previDate.toFormatString("yyyy年mm月dd日"); _dayElement.value = _previDate.toFormatString("yyyy年mm月dd日"); _dayElement.style.color = this.style.moreDayColor; _previDay++; }else { _dayElement.innerHTML = ""; _dayElement.title = ""; } } else if(_day > _monthDays[_month]) { //获取下个月的日期 if(this.showMoreDay) { var _nextDate = new Date(_year,_month + 1,_nextDay); _dayElement.innerHTML = _nextDay; _dayElement.title = _nextDate.toFormatString("yyyy年mm月dd日"); _dayElement.value = _nextDate.toFormatString(this.dateFormat); _dayElement.style.color = this.style.moreDayColor; _nextDay++; }else { _dayElement.innerHTML = ""; _dayElement.title = ""; } } else if(i >= new Date(_year,_month,1).getDay() && _day <= _monthDays[_month]) { //获取本月日期 _dayElement.innerHTML = _day; if(_day == _date.getDate()) { this.onMouseOver(_dayElement); _dayElement.onmouseover = Function(""); _dayElement.onmouseout = Function(""); } if(this.isHoliday(_year,_month,_day)) { _dayElement.style.color = this.style.bodyHolidayFontColor; } var _curDate = new Date(_year, _month, _day); _dayElement.title = _curDate.toFormatString("yyyy年mm月dd日"); _dayElement.value = _curDate.toFormatString(this.dateFormat); _day++; } else { _dayElement.innerHTML = ""; _dayElement.title = ""; } } var _menu = $F("cdrMenu"); _menu.style.display = "none"; }; Calendar.prototype.bindHeader = function() { var _curYear = $F("currentYear"); var _curMonth = $F("currentMonth"); var _watermark = $F("cdrWatermark"); _curYear.innerHTML = this.date.toFormatString("yyyy年"); _curMonth.innerHTML = this.date.toFormatString("mm月"); _watermark.innerHTML = this.date.getFullYear(); }; Calendar.prototype.getToday = function() { var _date = new Date(); this.bindDate(_date.toFormatString("-")); }; Calendar.prototype.isHoliday = function(year,month,date) { var _date = new Date(year,month,date); return (_date.getDay() == 6 || _date.getDay() == 0); }; Calendar.prototype.onMouseOver = function(obj) { obj.className = "dayOver"; }; Calendar.prototype.onMouseOut = function(obj) { obj.className = "dayOut"; }; Calendar.prototype.onClick = function(obj) { if(obj.innerHTML != "") this.dateInput.value = obj.value; this.hide(); }; Calendar.prototype.onChangeYear = function(isnext) { var _year = this.date.getFullYear(); var _month = this.date.getMonth() + 1; var _date = this.date.getDate(); if(_year > 999 && _year <10000) { if(isnext){_year++;}else{ _year --;} } else { alert("年份超出范围(1000-9999)!"); } this.bindDate(_year + '-' + _month + '-' + _date); }; Calendar.prototype.onChangeMonth = function(isnext) { var _year = this.date.getFullYear(); var _month = this.date.getMonth() + 1; var _date = this.date.getDate(); if(isnext){ _month ++;} else {_month--;} if(_year > 999 && _year <10000) { if(_month < 1) {_month = 12; _year--;} if(_month > 12) {_month = 1; _year++;} } else { alert("年份超出范围(1000-9999)!"); } this.bindDate(_year + '-' + _month + '-' + _date); }; Calendar.prototype.showMenu = function(isyear) { var _menu = $F("cdrMenu"); if(isyear != null) { var _obj = (isyear)? $F("currentYear") : $F("currentMonth"); if(isyear) { this.getYearMenu(this.date.getFullYear() - 5); } else { this.getMonthMenu(); } _menu.style.top = (_obj.offsetTop + _obj.offsetHeight) + 'px'; _menu.style.left = _obj.offsetLeft + 'px'; _menu.style.width = _obj.offsetWidth + 'px'; } if (this.timer != null) clearTimeout(this.timer); _menu.style.display=""; } Calendar.prototype.hideMenu = function() { var _obj = $F("cdrMenu"); this.timer = window.setTimeout(function(){_obj.style.display='none';},500); } Number.prototype.NaN0 = function() { return isNaN(this) ? 0 : this; } Number.prototype.toFormatString = function(){ var _str = '00'+this; return _str.substring(_str.length-2,_str.length); } Date.prototype.toFormatString = function(fs) { if(fs.length == 1) { return this.getFullYear() + fs + (this.getMonth() + 1) + fs + this.getDate(); } fs = fs.replace("yyyy",this.getFullYear()); fs = fs.replace("mm",addZero(this.getMonth()+1)); fs = fs.replace("dd",addZero(this.getDate())); return fs; } /******************************************公用方法及变量********************************************************/ var inputObj = null; //输入对象 var targetObj = null; //单击目标对象 var dragObj = null; //拖动目标对象 var dragObj1 = null; //拖动目标对象 var mouseOffset = null; //拖动目标的位置 //获取对象 function $(obj) { if(document.getElementById) { return document.getElementById(obj); } else { alert("浏览器不支持!"); } } function $F(obj) { if($('Calendar').contentDocument) return $('Calendar').contentDocument.getElementById(obj); else return $('Calendar').document.getElementById(obj); } //获取鼠标位置 function mouseCoords(ev) { if(ev.pageX || ev.pageY){ return {x:ev.pageX, y:ev.pageY}; } return { x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, y:ev.clientY + document.body.scrollTop - document.body.clientTop }; } //获取目标的绝对位置 function getPosition(e) { var left = 0; var top = 0; while (e.offsetParent){ left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0); top += e.offsetTop + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0); e = e.offsetParent; } left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0); top += e.offsetTop + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0); return {x:left, y:top}; } //获取鼠标的偏移值 function getMouseOffset(target, ev) { ev = ev || window.event; var docPos = getPosition(target); var mousePos = mouseCoords(ev); return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; } //关闭日历 function closeCalendar(evt){ evt = evt || window.event; var _target= evt.target || evt.srcElement; if(!_target.getAttribute("Author") && _target != inputObj && _target != targetObj) { $("Calendar").style.display = "none"; $F("inCalendar").style.display = "none"; } } //拖动日历开始 function dragStart(evt){ evt = evt || window.event; var _target= evt.target || evt.srcElement; if(_target.getAttribute("Author") == "alin_bar") { dragObj = $("Calendar"); mouseOffset = getMouseOffset(dragObj, evt); dragObj1 = $F("inCalendar"); mouseOffset = getMouseOffset(dragObj1, evt); } } //拖动日历中 function drag(evt) { evt = evt || window.event; if(dragObj) { var mousePos = mouseCoords(evt); dragObj.style.left = (mousePos.x - mouseOffset.x) + 'px'; dragObj.style.top = (mousePos.y - mouseOffset.y) + 'px'; dragObj1.style.left = (mousePos.x - mouseOffset.x) + 'px'; dragObj1.style.top = (mousePos.y - mouseOffset.y) + 'px'; } } //拖动结束 function dragEnd(evt) { dragObj = null; } function addZero(n){return(("00"+ n).substr(("00"+ n).length-2));} /**********************************End 公用方法**********************************************/ document.onclick = closeCalendar; document.onmousedown = dragStart; document.onmousemove = drag; document.onmouseup = dragEnd; /*****************************************************结束************************************************************/
本来把你的日历II改了,使之能不被select挡住,还有个修改就是你的日历好像不支持format,这个也改了一下;现在你出III了,这两个问题都解决了,那还是用你的正版。
顺便问一句,你是姓曹么?是的话那咱们是本家呵呵
和prototype的$系列有冲突,只能改方法名了。
getPosition*()没有将parent的scrollLeft和scrollTop计算在内,放在层里定位会有问题。
谢谢你的建议和关注
呵呵,我也姓曹。
show里面的判断没有算上scroolTop
应该这样判断
if((document.body.clientHeight – ((_target.y-document.body.scrollTop) + _evObj.clientHeight)) >= _obj.clientHeight)[s:1]
呵呵,又是我.
出新版本啦.我刚才在我的项目里用了,
可是有个问题一直解决不了:
就是这个日期控件放到一个IFRAME里的话,如果TEXTBOX在这个IFRAME的上部,这个控件会被IFRAME外面的页面挡住,还有,也是在IFRAME里,我用的时候点上面选择月份年份的时候,提示脚本错误,无法选择说是'top.cdr'为空或不是对象.希望二林能够解决这两个问题.!
必须顶~~ 嘎嘎 好东东啊~~ 支持firefox~~
我和wtb提的问题一样,看看能不能解决?
top.cdr为空或不是对象问题是因为大家在frame中使用这个日期控件,top就会指向最顶层的window,而不是日期控件所在的window了。
我是这样改的,将所有的“top.” 去掉,就可以了。暂时还没发现因此导致的其他问题。
不明白alin使用top.的缘故是什么,他也很久没来更新了。在QQ上能见到但是不理人,可能很忙吧,祝他一切顺利。
很不错啊,谢谢
IFRAME的里面
将所有的“top.” 去掉 导致firefox下 日期年 月下拉菜单不能正常显示了
不去的话,在有IFRAME的里面IE6有问题
给2点建议:
1. 希望把选择“年份”和“月份”的地方改为select下拉菜单。
2.希望把底部的“今天:XX年XX月XX日”那里改为点击后直接传递值到指定的文本输入框内。
好象不兼容 prototype
我在无数个web项目中都用的是第一版,期间不断擅自改进、适应,一直用到现在。到如今都感觉差不多半个是我自己的了:当然是说有了感情的意思。
今年是哪一年了?我的天哪,已经是21年了。权当此留言为一种十几年来未作出的感谢。
你能用到现在也挺不容易的:),现在前端技术日新月异,基于工程化的前端开发是未来发展的方向,大量前端UI已经非常好用了,所以没必要守旧,站在巨人的肩上才能看的更远。