DatePicker是个很常见的组件。我大致搜了一下,满大篇的demo。各大框架也把DatePicker纳入基本的组件库里。jQ的ui有,YUI的widget里也有。而且也封装的结结实实,兼容性,通用性,都做得挺好。于是在代码完善的同时,代码量自然也不会少。即使建立在基础库之上,代码也是好几百行。
真正使用的时候可能并不需要这么完善的功能。咱们就写个简陋点的东西,够自己用就行了。
而且以前有朋友提出我发的东西都是一些娱乐货,没有什么实用性,这次就当是个开始,抛个砖,以后时不时发个带一些实用性的东东。
<!-- 以下demo没有什么出彩的地方,仅供有需要的朋友看看 -->
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>DatePicker</title> <meta name="author" content="hongru.chen" /> <style> .date-picker-wp { display: none; position: absolute; background: #f1f1f1; left: 40px; top: 40px; border-top: 4px solid #3879d9; } .date-picker-wp table { border: 1px solid #ddd; } .date-picker-wp td { background: #fafafa; width: 22px; height: 18px; border: 1px solid #ccc; font-size: 12px; text-align: center; } .date-picker-wp td.noborder { border: none; background: none; } .date-picker-wp td a { color: #1c93c4; text-decoration: none; } .strong {font-weight: bold} .hand {cursor: pointer; color: #3879d9} </style> </head> <body> <input type="text" id="date-input" /> <input type="text" id="demo2" /><br/> <select><option>岑安</option></select> </body> </html>
以下是源码:
var $ = function (i) { return document.getElementById(i)},
addEvent = function (o, e, f) {o.addEventListener ? o.addEventListener(e, f, false ) : o.attachEvent( ' on ' + e, function (){f.call(o)})},
getPos = function (el) {
for ( var pos = {x: 0 , y: 0 }; el; el = el.offsetParent) {
pos.x += el.offsetLeft;
pos.y += el.offsetTop;
}
return pos;
}
var init = function (n, config) {
window[n] = this ;
Date.prototype._fd = function () { var d = new Date( this ); d.setDate( 1 ); return d.getDay()};
Date.prototype._fc = function () { var d1 = new Date( this ), d2 = new Date( this ); d1.setDate( 1 ); d2.setDate( 1 ); d2.setMonth(d2.getMonth() + 1 ); return (d2 - d1) / 86400000;};
this .n = n;
this .config = config;
this .D = new Date;
this .el = $(config.inputId);
this .el.title = this .n + ' DatePicker ' ;
this .update();
this .bind();
}
init.prototype = {
update : function (y, m) {
var con = [], week = [ ' Su ' , ' Mo ' , ' Tu ' , ' We ' , ' Th ' , ' Fr ' , ' Sa ' ], D = this .D, _this = this ;
fn = function (a, b) { return ' <td title=" ' + _this.n + ' DatePicker" class="noborder hand" οnclick=" ' + _this.n + ' .update( ' + a + ' )"> ' + b + ' </td> ' },
_html = ' <table cellpadding=0 cellspacing=2> ' ;
y && D.setYear(D.getFullYear() + y);
m && D.setMonth(D.getMonth() + m);
var year = D.getFullYear(), month = D.getMonth() + 1 , date = D.getDate();
for ( var i = 0 ; i < week.length; i ++ ) con.push( ' <td title=" ' + this .n + ' DatePicker" class="noborder"> ' + week[i] + ' </td> ' );
for ( var i = 0 ; i < D._fd(); i ++ ) con.push( ' <td title=" ' + this .n + ' DatePicker" class="noborder"> </td> ' );
for ( var i = 0 ; i < D._fc(); i ++ ) con.push( ' <td class="hand" οnclick=" ' + this .n + ' .fillInput( ' + year + ' , ' + month + ' , ' + (i + 1 ) + ' )"> ' + (i + 1 ) + ' </td> ' );
var toend = con.length % 7 ;
if (toend != 0 ) for ( var i = 0 ; i < 7 - toend; i ++ ) con.push( ' <td class="noborder"> </td> ' );
_html += ' <tr> ' + fn( " -1, null " , " << " ) + fn( " null, -1 " , " < " ) + ' <td title=" ' + this .n + ' DatePicker" colspan=3 class="strong"> ' + year + ' / ' + month + ' / ' + date + ' </td> ' + fn( " null, 1 " , " > " ) + fn( " 1, null " , " >> " ) + ' </tr> ' ;
for ( var i = 0 ; i < con.length; i ++ ) _html += (i == 0 ? ' <tr> ' : i % 7 == 0 ? ' </tr><tr> ' : '' ) + con[i] + (i == con.length - 1 ? ' </tr> ' : '' );
!! this .box ? this .box.innerHTML = _html : this .createBox(_html);
},
fillInput : function (y, m, d) {
var s = this .config.seprator || ' / ' ;
this .el.value = y + s + m + s + d;
this .box.style.display = ' none ' ;
},
show : function () {
var s = this .box.style, is = this .mask.style;
s[ ' left ' ] = is[ ' left ' ] = getPos( this .el).x + ' px ' ;
s[ ' top ' ] = is[ ' top ' ] = getPos( this .el).y + this .el.offsetHeight + ' px ' ;
s[ ' display ' ] = is[ ' display ' ] = ' block ' ;
is[ ' width ' ] = this .box.offsetWidth - 2 + ' px ' ;
is[ ' height ' ] = this .box.offsetHeight - 2 + ' px ' ;
},
hide : function () {
this .box.style.display = ' none ' ;
this .mask.style.display = ' none ' ;
},
bind : function () {
var _this = this ;
addEvent(document, ' click ' , function (e) {
e = e || window.event;
var t = e.target || e.srcElement;
if (t.title != _this.n + ' DatePicker ' ) {_this.hide()} else {_this.show()}
})
},
createBox : function (html) {
var box = this .box = document.createElement( ' div ' ), mask = this .mask = document.createElement( ' iframe ' );
box.className = this .config.className || ' datepicker ' ;
mask.src = ' javascript:false ' ;
mask.frameBorder = 0 ;
box.style.cssText = ' position:absolute;display:none;z-index:9999 ' ;
mask.style.cssText = ' position:absolute;display:none;z-index:9998 ' ;
box.title = this .n + ' DatePicker ' ;
box.innerHTML = html;
document.body.appendChild(box);
document.body.appendChild(mask);
return box;
}
}
return init;
}();
调用方式:
inputId: ' date-input ' ,
className: ' date-picker-wp ' ,
seprator: ' - '
});
第一个参数:实例名,
第二个参数一个对象字面量,包括输入框的id(必须),弹出日历box的className,日期样式的分隔符如‘-’,‘/’,等。后两个可省略,默认值‘datepicker’,‘/’。