終於把jQuery拼寫正確了哈,哈哈javascript也是區分大小寫的,因此確實不能寫錯,今天我來和你們分享的是日期選擇控件的實現,功能也許不夠強大,可是可以知足需求。javascript
我以前也寫過(正確的說是改過一個日期選擇控件,點擊這裏查看),看下截圖哈,也很酷的,windows風格哦。 css
可是也有些問題,第一畫日曆有點慢,第二兼容性不太好IE Only,第三它不是基於jQuery的哈哈。html
那仍是老規矩,作以前先看下效果java
這下是更酷的Ext風格了。
從上圖咱們能夠看出這個控件其實有兩個視圖一個日期月視圖,還有一個是年月選擇視圖。
1:仍是先從HTML入手windows
日期控件肯定HTML其實仍是比較簡單,由於明擺着是列表的數據格式,固然主要是採用table了。
兩個視圖分別用兩個Div包裹,控制div的顯示隱藏便可以切換視圖了。完整的HTMl結構你們能夠用IEDeveloper看一下Demo的結構,我本身截了一個圖 數組
2:根據HTML和效果圖編寫CSSapp
其實由於是Ext風格的,因此直接copy的ext的css和圖片。。ssh
CSS也就不分析了,直接上代碼。ide
由於博客園的語法高亮不支持CSS,因此就不貼出來了,給個下載地址吧:函數
http://xuanye.cloudapp.net/Theme/Default/dp.css
全部用到的圖片:
3:搞定了CSS以後呢,就開始編寫咱們javascript了。
上來就是一個完整代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
;(
function
($) {
var
userAgent = window.navigator.userAgent.toLowerCase();
$.browser.msie8 = $.browser.msie && /msie 8\.0/i.test(userAgent);
$.browser.msie7 = $.browser.msie && /msie 7\.0/i.test(userAgent);
$.browser.msie6 = !$.browser.msie8 && !$.browser.msie7 && $.browser.msie && /msie 6\.0/i.test(userAgent);
Date.prototype.Format =
function
(format) {
var
o = {
"M+"
:
this
.getMonth() + 1,
"d+"
:
this
.getDate(),
"h+"
:
this
.getHours(),
"H+"
:
this
.getHours(),
"m+"
:
this
.getMinutes(),
"s+"
:
this
.getSeconds(),
"q+"
: Math.floor((
this
.getMonth() + 3) / 3),
"w"
:
"0123456"
.indexOf(
this
.getDay()),
"S"
:
this
.getMilliseconds()
};
if
(/(y+)/.test(format)) {
format = format.replace(RegExp.$1, (
this
.getFullYear() +
""
).substr(4 - RegExp.$1.length));
}
for
(
var
k
in
o) {
if
(
new
RegExp(
"("
+ k +
")"
).test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length == 1 ? o[k] :
(
"00"
+ o[k]).substr((
""
+ o[k]).length));
}
return
format;
};
function
DateAdd(interval, number, idate) {
number = parseInt(number);
var
date;
if
(
typeof
(idate) ==
"string"
) {
date = idate.split(/\D/);
eval(
"var date = new Date("
+ date.join(
","
) +
")"
);
}
if
(
typeof
(idate) ==
"object"
) {
date =
new
Date(idate.toString());
}
switch
(interval) {
case
"y"
: date.setFullYear(date.getFullYear() + number);
break
;
case
"m"
: date.setMonth(date.getMonth() + number);
break
;
case
"d"
: date.setDate(date.getDate() + number);
break
;
case
"w"
: date.setDate(date.getDate() + 7 * number);
break
;
case
"h"
: date.setHours(date.getHours() + number);
break
;
case
"n"
: date.setMinutes(date.getMinutes() + number);
break
;
case
"s"
: date.setSeconds(date.getSeconds() + number);
break
;
case
"l"
: date.setMilliseconds(date.getMilliseconds() + number);
break
;
}
return
date;
};
$.fn.datepicker =
function
(o) {
var
def = {
weekStart: 0,
weekName: [
"日"
,
"一"
,
"二"
,
"三"
,
"四"
,
"五"
,
"六"
],
//星期的格式
monthName: [
"一"
,
"二"
,
"三"
,
"四"
,
"五"
,
"六"
,
"七"
,
"八"
,
"九"
,
"十"
,
"十一"
,
"十二"
],
//月份的格式
monthp:
"月"
,
Year:
new
Date().getFullYear(),
//定義年的變量的初始值
Month:
new
Date().getMonth() + 1,
//定義月的變量的初始值
Day:
new
Date().getDate(),
//定義日的變量的初始值
today:
new
Date(),
btnOk:
" 肯定 "
,
btnCancel:
" 取消 "
,
btnToday:
"今天"
,
inputDate:
null
,
onReturn:
false
,
version:
"1.1"
,
applyrule:
false
,
//function(){};return rule={startdate,endate};
showtarget:
null
,
picker:
""
};
$.extend(def, o);
var
cp = $(
"#BBIT_DP_CONTAINER"
);
if
(cp.length == 0) {
var
cpHA = [];
cpHA.push(
"<div id='BBIT_DP_CONTAINER' class='bbit-dp' style='width:175px;z-index:999;'>"
);
if
($.browser.msie6) {
cpHA.push(
'<iframe style="position:absolute;z-index:-1;width:100%;height:100%;top:0;left:0;scrolling:no;" frameborder="0" src="about:blank"></iframe>'
);
}
cpHA.push(
"<table class='dp-maintable' cellspacing='0' cellpadding='0' style='width:175px;'><tbody><tr><td>"
);
//頭喲
cpHA.push(
"<table class='bbit-dp-top' cellspacing='0'><tr><td class='bbit-dp-top-left'> <a id='BBIT_DP_LEFTBTN' href='javascript:void(0);' title='向前一個月'> </a></td><td class='bbit-dp-top-center' align='center'><em><button id='BBIT_DP_YMBTN'>九月 2009</button></em></td><td class='bbit-dp-top-right'><a id='BBIT_DP_RIGHTBTN' href='javascript:void(0);' title='向後一個月'> </a></td></tr></table>"
);
cpHA.push(
"</td></tr>"
);
cpHA.push(
"<tr><td>"
);
//周
cpHA.push(
"<table id='BBIT_DP_INNER' class='bbit-dp-inner' cellspacing='0'><thead><tr>"
);
//生成周
for
(
var
i = def.weekStart, j = 0; j < 7; j++) {
cpHA.push(
"<th><span>"
, def.weekName[i],
"</span></th>"
);
if
(i == 6) { i = 0; }
else
{ i++; }
}
cpHA.push(
"</tr></thead>"
);
//生成tBody,須要從新生成的
cpHA.push(
"<tbody></tbody></table>"
);
//生成tBody結束
cpHA.push(
"</td></tr>"
);
cpHA.push(
"<tr><td class='bbit-dp-bottom' align='center'><button id='BBIT-DP-TODAY'>"
, def.btnToday,
"</button></td></tr>"
);
cpHA.push(
"</tbody></table>"
);
//輸出下來框
cpHA.push(
"<div id='BBIT-DP-MP' class='bbit-dp-mp' style='z-index:auto;'><table id='BBIT-DP-T' style='width: 175px; height: 193px' border='0' cellspacing='0'><tbody>"
);
cpHA.push(
"<tr>"
);
//1月,7月 按鈕兩個
cpHA.push(
"<td class='bbit-dp-mp-month' xmonth='0'><a href='javascript:void(0);'>"
, def.monthName[0],
"</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='6'><a href='javascript:void(0);'>"
, def.monthName[6],
"</a></td><td class='bbit-dp-mp-ybtn' align='middle'><a id='BBIT-DP-MP-PREV' class='bbit-dp-mp-prev'></a></td><td class='bbit-dp-mp-ybtn' align='middle'><a id='BBIT-DP-MP-NEXT' class='bbit-dp-mp-next'></a></td>"
);
cpHA.push(
"</tr>"
);
cpHA.push(
"<tr>"
);
cpHA.push(
"<td class='bbit-dp-mp-month' xmonth='1'><a href='javascript:void(0);'>"
, def.monthName[1],
"</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='7'><a href='javascript:void(0);'>"
, def.monthName[7],
"</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>"
);
cpHA.push(
"</tr>"
);
cpHA.push(
"<tr>"
);
cpHA.push(
"<td class='bbit-dp-mp-month' xmonth='2'><a href='javascript:void(0);'>"
, def.monthName[2],
"</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='8'><a href='javascript:void(0);'>"
, def.monthName[8],
"</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>"
);
cpHA.push(
"</tr>"
);
cpHA.push(
"<tr>"
);
cpHA.push(
"<td class='bbit-dp-mp-month' xmonth='3'><a href='javascript:void(0);'>"
, def.monthName[3],
"</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='9'><a href='javascript:void(0);'>"
, def.monthName[9],
"</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>"
);
cpHA.push(
"</tr>"
);
cpHA.push(
"<tr>"
);
cpHA.push(
"<td class='bbit-dp-mp-month' xmonth='4'><a href='javascript:void(0);'>"
, def.monthName[4],
"</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='10'><a href='javascript:void(0);'>"
, def.monthName[10],
"</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>"
);
cpHA.push(
"</tr>"
);
cpHA.push(
"<tr>"
);
cpHA.push(
"<td class='bbit-dp-mp-month' xmonth='5'><a href='javascript:void(0);'>"
, def.monthName[5],
"</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='11'><a href='javascript:void(0);'>"
, def.monthName[11],
"</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>"
);
cpHA.push(
"</tr>"
);
cpHA.push(
"<tr class='bbit-dp-mp-btns'>"
);
cpHA.push(
"<td colspan='4'><button id='BBIT-DP-MP-OKBTN' class='bbit-dp-mp-ok'>"
, def.btnOk,
"</button><button id='BBIT-DP-MP-CANCELBTN' class='bbit-dp-mp-cancel'>"
, def.btnCancel,
"</button></td>"
);
cpHA.push(
"</tr>"
);
cpHA.push(
"</tbody></table>"
);
cpHA.push(
"</div>"
);
cpHA.push(
"</div>"
);
var
s = cpHA.join(
""
);
$(document.body).append(s);
var
cp = $(
"#BBIT_DP_CONTAINER"
);
initevents();
}
function
initevents() {
//1 today btn;
$(
"#BBIT-DP-TODAY"
).click(returntoday);
cp.click(returnfalse);
$(
"#BBIT_DP_INNER tbody"
).click(tbhandler);
$(
"#BBIT_DP_LEFTBTN"
).click(prevm);
$(
"#BBIT_DP_RIGHTBTN"
).click(nextm);
$(
"#BBIT_DP_YMBTN"
).click(showym);
$(
"#BBIT-DP-MP"
).click(mpclick);
$(
"#BBIT-DP-MP-PREV"
).click(mpprevy);
$(
"#BBIT-DP-MP-NEXT"
).click(mpnexty);
$(
"#BBIT-DP-MP-OKBTN"
).click(mpok);
$(
"#BBIT-DP-MP-CANCELBTN"
).click(mpcancel);
}
function
mpcancel() {
$(
"#BBIT-DP-MP"
).animate({ top: -193 }, { duration: 200, complete:
function
() { $(
"#BBIT-DP-MP"
).hide(); } });
return
false
;
}
function
mpok() {
def.Year = def.cy;
def.Month = def.cm + 1;
def.Day = 1;
$(
"#BBIT-DP-MP"
).animate({ top: -193 }, { duration: 200, complete:
function
() { $(
"#BBIT-DP-MP"
).hide(); } });
writecb();
return
false
;
}
function
mpprevy() {
var
y = def.ty - 10
def.ty = y;
rryear(y);
return
false
;
}
function
mpnexty() {
var
y = def.ty + 10
def.ty = y;
rryear(y);
return
false
;
}
function
rryear(y) {
var
s = y - 4;
var
ar = [];
for
(
var
i = 0; i < 5; i++) {
ar.push(s + i);
ar.push(s + i + 5);
}
$(
"#BBIT-DP-MP td.bbit-dp-mp-year"
).each(
function
(i) {
if
(def.Year == ar[i]) {
$(
this
).addClass(
"bbit-dp-mp-sel"
);
}
else
{
$(
this
).removeClass(
"bbit-dp-mp-sel"
);
}
$(
this
).html(
"<a href='javascript:void(0);'>"
+ ar[i] +
"</a>"
).attr(
"xyear"
, ar[i]);
});
}
function
mpclick(e) {
var
panel = $(
this
);
var
et = e.target || e.srcElement;
var
td = getTd(et);
if
(td ==
null
) {
return
false
;
}
if
($(td).hasClass(
"bbit-dp-mp-month"
)) {
if
(!$(td).hasClass(
"bbit-dp-mp-sel"
)) {
var
ctd = panel.find(
"td.bbit-dp-mp-month.bbit-dp-mp-sel"
);
if
(ctd.length > 0) {
ctd.removeClass(
"bbit-dp-mp-sel"
);
}
$(td).addClass(
"bbit-dp-mp-sel"
)
def.cm = parseInt($(td).attr(
"xmonth"
));
}
}
if
($(td).hasClass(
"bbit-dp-mp-year"
)) {
if
(!$(td).hasClass(
"bbit-dp-mp-sel"
)) {
var
ctd = panel.find(
"td.bbit-dp-mp-year.bbit-dp-mp-sel"
);
if
(ctd.length > 0) {
ctd.removeClass(
"bbit-dp-mp-sel"
);
}
$(td).addClass(
"bbit-dp-mp-sel"
)
def.cy = parseInt($(td).attr(
"xyear"
));
}
}
return
false
;
}
function
showym() {
var
mp = $(
"#BBIT-DP-MP"
);
var
y = def.Year;
def.cy = def.ty = y;
var
m = def.Month - 1;
def.cm = m;
var
ms = $(
"#BBIT-DP-MP td.bbit-dp-mp-month"
);
for
(
var
i = ms.length - 1; i >= 0; i--) {
var
ch = $(ms[i]).attr(
"xmonth"
);
if
(ch == m) {
$(ms[i]).addClass(
"bbit-dp-mp-sel"
);
}
else
{
$(ms[i]).removeClass(
"bbit-dp-mp-sel"
);
}
}
rryear(y);
mp.css(
"top"
, -193).show().animate({ top: 0 }, { duration: 200 });
}
function
getTd(elm) {
if
(elm.tagName.toUpperCase() ==
"TD"
) {
return
elm;
}
else
if
(elm.tagName.toUpperCase() ==
"BODY"
) {
return
null
;
}
else
{
var
p = $(elm).parent();
if
(p.length > 0) {
if
(p[0].tagName.toUpperCase() !=
"TD"
) {
return
getTd(p[0]);
}
else
{
return
p[0];
}
}
}
return
null
;
}
function
tbhandler(e) {
var
et = e.target || e.srcElement;
var
td = getTd(et);
if
(td ==
null
) {
return
false
;
}
var
$td = $(td);
if
(!$(td).hasClass(
"bbit-dp-disabled"
)) {
var
s = $td.attr(
"xdate"
);
var
arrs = s.split(
"-"
);
cp.data(
"indata"
,
new
Date(arrs[0], parseInt(arrs[1], 10) - 1, arrs[2]));
returndate();
}
return
false
;
}
function
returnfalse() {
return
false
;
}
function
prevm() {
if
(def.Month == 1) {
def.Year--;
def.Month = 12;
}
else
{
def.Month--
}
writecb();
return
false
;
}
function
nextm() {
if
(def.Month == 12) {
def.Year++;
def.Month = 1;
}
else
{
def.Month++
}
writecb();
return
false
;
}
function
returntoday() {
cp.data(
"indata"
,
new
Date());
returndate();
}
function
returndate() {
var
ct = cp.data(
"ctarget"
);
var
ck = cp.data(
"cpk"
);
var
re = cp.data(
"onReturn"
);
var
ndate = cp.data(
"indata"
)
var
ads = cp.data(
"ads"
);
var
ade = cp.data(
"ade"
);
var
dis =
false
;
if
(ads && ndate < ads) {
dis =
true
;
}
if
(ade && ndate > ade) {
dis =
true
;
}
if
(dis) {
return
;
}
if
(re && jQuery.isFunction(re)) {
re.call(ct[0], cp.data(
"indata"
));
}
else
{
ct.val(cp.data(
"indata"
).Format(
"yyyy-MM-dd"
));
}
ck.attr(
"isshow"
,
"0"
);
cp.removeData(
"ctarget"
).removeData(
"cpk"
).removeData(
"indata"
).removeData(
"onReturn"
)
.removeData(
"ads"
).removeData(
"ade"
);
cp.css(
"visibility"
,
"hidden"
);
ct = ck =
null
;
}
function
writecb() {
var
tb = $(
"#BBIT_DP_INNER tbody"
);
$(
"#BBIT_DP_YMBTN"
).html(def.monthName[def.Month - 1] + def.monthp +
" "
+ def.Year);
var
firstdate =
new
Date(def.Year, def.Month - 1, 1);
var
diffday = def.weekStart - firstdate.getDay();
var
showmonth = def.Month - 1;
if
(diffday > 0) {
diffday -= 7;
}
var
startdate = DateAdd(
"d"
, diffday, firstdate);
var
enddate = DateAdd(
"d"
, 42, startdate);
var
ads = cp.data(
"ads"
);
var
ade = cp.data(
"ade"
);
var
bhm = [];
var
tds = def.today.Format(
"yyyy-MM-dd"
);
var
indata = cp.data(
"indata"
);
var
ins = indata !=
null
? indata.Format(
"yyyy-MM-dd"
) :
""
;
for
(
var
i = 1; i <= 42; i++) {
if
(i % 7 == 1) {
bhm.push(
"<tr>"
);
}
var
ndate = DateAdd(
"d"
, i - 1, startdate);
var
tdc = [];
var
dis =
false
;
if
(ads && ndate < ads) {
dis =
true
;
}
if
(ade && ndate > ade) {
dis =
true
;
}
if
(ndate.getMonth() < showmonth) {
tdc.push(
"bbit-dp-prevday"
);
}
else
if
(ndate.getMonth() > showmonth) {
tdc.push(
"bbit-dp-nextday"
);
}
if
(dis) {
tdc.push(
"bbit-dp-disabled"
);
}
else
{
tdc.push(
"bbit-dp-active"
);
}
var
s = ndate.Format(
"yyyy-MM-dd"
);
if
(s == tds) {
tdc.push(
"bbit-dp-today"
);
}
if
(s == ins) {
tdc.push(
"bbit-dp-selected"
);
}
bhm.push(
"<td class='"
, tdc.join(
" "
),
"' title='"
, ndate.Format(
"yyyy-MM-dd"
),
"' xdate='"
, ndate.Format(
"yyyy-M-d"
),
"'><a href='javascript:void(0);'><em><span>"
, ndate.getDate(),
"</span></em></a></td>"
);
if
(i % 7 == 0) {
bhm.push(
"</tr>"
);
}
}
tb.html(bhm.join(
""
));
}
var
dateReg = /^(\d{1,4})(-|\/|.)(\d{1,2})\2(\d{1,2})$/;
return
$(
this
).each(
function
() {
var
obj = $(
this
).addClass(
"bbit-dp-input"
);
var
picker = $(def.picker);
def.showtarget ==
null
&& obj.after(picker);
picker.click(
function
(e) {
var
isshow = $(
this
).attr(
"isshow"
);
//先隱藏
var
me = $(
this
);
if
(cp.css(
"visibility"
) ==
"visible"
) {
cp.css(
" visibility"
,
"hidden"
);
}
if
(isshow ==
"1"
) {
me.attr(
"isshow"
,
"0"
);
cp.removeData(
"ctarget"
).removeData(
"cpk"
).removeData(
"indata"
).removeData(
"onReturn"
);
return
false
;
}
var
v = obj.val();
if
(v !=
""
) {
v = v.match(dateReg);
}
if
(v ==
null
|| v ==
""
) {
def.Year =
new
Date().getFullYear();
def.Month =
new
Date().getMonth() + 1;
def.Day =
new
Date().getDate();
def.inputDate =
null
}
else
{
def.Year = parseInt(v[1], 10);
def.Month = parseInt(v[3], 10);
def.Day = parseInt(v[4], 10);
def.inputDate =
new
Date(def.Year, def.Month - 1, def.Day);
}
cp.data(
"ctarget"
, obj).data(
"cpk"
, me).data(
"indata"
, def.inputDate).data(
"onReturn"
, def.onReturn);
if
(def.applyrule && $.isFunction(def.applyrule)) {
var
rule = def.applyrule.call(obj, obj[0].id);
if
(rule) {
if
(rule.startdate) {
cp.data(
"ads"
, rule.startdate);
}
else
{
cp.removeData(
"ads"
);
}
if
(rule.enddate) {
cp.data(
"ade"
, rule.enddate);
}
else
{
cp.removeData(
"ade"
);
}
}
}
else
{
cp.removeData(
"ads"
).removeData(
"ade"
)
}
writecb();
$(
"#BBIT-DP-T"
).height(cp.height());
var
t = def.showtarget || obj;
var
pos = t.offset();
var
height = t.outerHeight();
var
newpos = { left: pos.left, top: pos.top + height };
var
w = cp.width();
var
h = cp.height();
var
bw = document.documentElement.clientWidth;
var
bh = document.documentElement.clientHeight;
if
((newpos.left + w) >= bw) {
newpos.left = bw - w - 2;
}
if
((newpos.top + h) >= bh) {
newpos.top = pos.top - h - 2;
}
if
(newpos.left < 0) {
newpos.left = 10;
}
if
(newpos.top < 0) {
newpos.top = 10;
}
$(
"#BBIT-DP-MP"
).hide();
newpos.visibility =
"visible"
;
cp.css(newpos);
//cp.show();
$(
this
).attr(
"isshow"
,
"1"
);
$(document).one(
"click"
,
function
(e) {
me.attr(
"isshow"
,
"0"
);
cp.removeData(
"ctarget"
).removeData(
"cpk"
).removeData(
"indata"
);
cp.css(
"visibility"
,
"hidden"
);
});
return
false
;
});
});
};
})(jQuery);
|
那接着就是分析一下實現的主要過程和一些注意的要點:
首先仍是套版化編寫jQuery控件的套子:
1
2
3
4
5
|
;(
function
($) {
//也可使用$.fn.extend(datepicker:function(o){})
$.fn.datepicker=
function
(o) {
}
})(jQuery);
|
這樣作的好處上篇已經講過了 ,就不重述了
接着就是定義默認的參數,已在代碼中添加了註釋說明這些參數的意義,有幾個參數是爲了多語言而設置的,如weekName,monthName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var
def = {
weekStart: 0,
//一週開始的是星期幾0表明星期天
weekName: [
"日"
,
"一"
,
"二"
,
"三"
,
"四"
,
"五"
,
"六"
],
//星期的格式
monthName: [
"一"
,
"二"
,
"三"
,
"四"
,
"五"
,
"六"
,
"七"
,
"八"
,
"九"
,
"十"
,
"十一"
,
"十二"
],
//月份的格式
monthp:
"月"
,
//月的後綴
Year:
new
Date().getFullYear(),
//定義年的變量的初始值
Month:
new
Date().getMonth() + 1,
//定義月的變量的初始值
Day:
new
Date().getDate(),
//定義日的變量的初始值
today:
new
Date(),
//today
btnOk:
" 肯定 "
,
//肯定按鈕的文字
btnCancel:
" 取消 "
,
//取消按鈕的文字
btnToday:
"今天"
,
//今天按鈕的文字
inputDate:
null
,
//無用,只是在代碼中會用它存放數據
onReturn:
false
,
//當選擇日期後回調的函數
version:
"1.0"
,
//版本
applyrule:
false
,
//日期選擇規則,可設置可選擇的日期範圍function(){};return rule={startdate,endate};
showtarget:
null
,
//顯示載體,日曆展開式所依賴的對象,默認是對象自己
picker:
""
//附加點擊事件的對象
};
$.extend(def, o);
//用傳遞過來的參數來填充默認
|
第二部天然是初始化月視圖和年月選擇視圖的HTML了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
//給日期選擇控件一個特殊的ID,獲取這個ID的對象,判斷若是對象存在,則直接使用
// 日期的HTML採用單例,即一個頁面上只生成一份HTML
var
cp = $(
"#BBIT_DP_CONTAINER"
);
if
(cp.length == 0) {
var
cpHA = [];
//老規矩仍是用數組拼接html,最後用innerHTML的方式附加到容器,提高性能
cpHA.push(
"<div id='BBIT_DP_CONTAINER' class='bbit-dp' style='width:175px;z-index:999;'>"
);
if
($.browser.msie6) {
//若是是IE6彈出層遮蓋select
cpHA.push(
'<iframe style="position:absolute;z-index:-1;width:100%;height:100%;top:0;left:0;scrolling:no;" frameborder="0" src="about:blank"></iframe>'
);
}
cpHA.push(
"<table class='dp-maintable' cellspacing='0' cellpadding='0' style='width:175px;'><tbody><tr><td>"
);
//頭喲
cpHA.push(
"<table class='bbit-dp-top' cellspacing='0'><tr><td class='bbit-dp-top-left'> <a id='BBIT_DP_LEFTBTN' href='javascript:void(0);' title='向前一個月'> </a></td><td class='bbit-dp-top-center' align='center'><em><button id='BBIT_DP_YMBTN'>九月 2009</button></em></td><td class='bbit-dp-top-right'><a id='BBIT_DP_RIGHTBTN' href='javascript:void(0);' title='向後一個月'> </a></td></tr></table>"
);
cpHA.push(
"</td></tr>"
);
cpHA.push(
"<tr><td>"
);
//周
cpHA.push(
"<table id='BBIT_DP_INNER' class='bbit-dp-inner' cellspacing='0'><thead><tr>"
);
//生成周
for
(
var
i = def.weekStart, j = 0; j < 7; j++) {
cpHA.push(
"<th><span>"
, def.weekName[i],
"</span></th>"
);
if
(i == 6) { i = 0; }
else
{ i++; }
}
.....
//省略若干代碼
cpHA.push(
"</tbody></table>"
);
cpHA.push(
"</div>"
);
cpHA.push(
"</div>"
);
var
s = cpHA.join(
""
);
$(document.body).append(s);
//添加到body中
cp = $(
"#BBIT_DP_CONTAINER"
);
//再獲取一遍
initevents();
//初始化事件
}
|
這裏有一個關鍵點,就是日期的html輸出和事件初始化只作一次,由於基本上一頁上同時不會打開兩個。還有就是生成html中有一些特殊的自定義屬性哦,仔細看下就會發現的,這些屬性在後面的時間處理中都有很大的做用。那麼來看一下事件吧
1
2
3
4
5
6
7
8
9
10
11
|
$(
"#BBIT-DP-TODAY"
).click(returntoday);
//今天按鈕的事件
cp.click(returnfalse);
//阻止冒泡
$(
"#BBIT_DP_INNER tbody"
).click(tbhandler);
//給月視圖中間body添加click事件而不是給每一個td添加
$(
"#BBIT_DP_LEFTBTN"
).click(prevm);
//上個月
$(
"#BBIT_DP_RIGHTBTN"
).click(nextm);
//下個月
$(
"#BBIT_DP_YMBTN"
).click(showym);
//切換到年月視圖
$(
"#BBIT-DP-MP"
).click(mpclick);
//年月視圖的點擊事件,一樣用於分發
$(
"#BBIT-DP-MP-PREV"
).click(mpprevy);
//上一年
$(
"#BBIT-DP-MP-NEXT"
).click(mpnexty);
//下一年
$(
"#BBIT-DP-MP-OKBTN"
).click(mpok);
//ok按鈕的事件
$(
"#BBIT-DP-MP-CANCELBTN"
).click(mpcancel);
//cancel按鈕的事件
|
給每個須要點擊的元素加上事件哦,這裏有兩個地方比較特殊,一個是月視圖的點擊事件,傳統的作法就是給每一個td都加事件,可是這個時候個人td尚未呢,可是若是在每次生成td的時候來附加事件,那麼就由影響性能,因此直接給容器加了點擊事件,經過對事件源的判斷來分發事件,另一個年月選擇視圖,也是和上面同樣的邏輯,那麼咱們就拿月視圖的點擊事件來分析一下,其實每個td生成的時候都會註冊一個xdate自定義屬性 ,來看一下tbhandler函數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function
tbhandler(e) {
var
et = e.target || e.srcElement;
//找到事件源
var
td = getTd(et);
//事件源遞歸往上找td
if
(td ==
null
) {
return
false
;
}
var
$td = $(td);
if
(!$(td).hasClass(
"bbit-dp-disabled"
)) {
//若是不是禁用狀態
var
s = $td.attr(
"xdate"
);
//獲取td的自定義屬性日期數據
var
arrs = s.split(
"-"
);
cp.data(
"indata"
,
new
Date(arrs[0], parseInt(arrs[1], 10) - 1, arrs[2]));
returndate();
//返回日期
}
return
false
;
}
|
全部的日期選擇事件初始化好了(一次性的),接着就要給每個的picker添加點擊事件了
1
2
3
4
5
6
7
8
9
10
11
12
|
return
$(
this
).each(
function
() {
var
obj = $(
this
).addClass(
"bbit-dp-input"
);
//給input添加樣式
var
picker = $(def.picker);
//獲取picker對象
//若是showtarget不爲null這將picker註冊到input的後面
//不然用戶本身處理picker的位置,即picker在頁面上自己就已經存在
//你們能夠看看示例中1,3調用的區別
def.showtarget ==
null
&& obj.after(picker);
picker.click(
function
(e) {
...
//省略代碼
});
|
picker的點擊事件比較長,單獨拿出來說一下我想比較好,第一個要點是顯示隱藏事件的處理,第二個是窗口邊緣問題的處理,還有一個就是日期範圍規則的處理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
function
(e) {
//獲取當前是否顯示
var
isshow = $(
this
).attr(
"isshow"
);
var
me = $(
this
);
//若是顯示着,則隱藏,用於處理點擊一下picker顯示,再點擊picker隱藏的邏輯
if
(cp.css(
"visibility"
) ==
"visible"
) {
cp.css(
" visibility"
,
"hidden"
);
}
//一樣是若是顯示着
if
(isshow ==
"1"
) {
me.attr(
"isshow"
,
"0"
);
//remover臨時數據,由於是單例因此要表示當前是哪一個input
cp.removeData(
"ctarget"
).removeData(
"cpk"
).removeData(
"indata"
).removeData(
"onReturn"
);
return
false
;
//阻止冒泡
}
//若是隱藏着,獲取input的值
var
v = obj.val();
if
(v !=
""
) {
v = v.match(dateReg);
//驗證一下格式是否正確
}
if
(v ==
null
|| v ==
""
) {
//格式不正確或爲空則用當前日期
def.Year =
new
Date().getFullYear();
def.Month =
new
Date().getMonth() + 1;
def.Day =
new
Date().getDate();
def.inputDate =
null
}
else
{
//不然使用input的日期
def.Year = parseInt(v[1], 10);
def.Month = parseInt(v[3], 10);
def.Day = parseInt(v[4], 10);
def.inputDate =
new
Date(def.Year, def.Month - 1, def.Day);
}
//註冊臨時數據,由於是單例的緣故
cp.data(
"ctarget"
, obj).data(
"cpk"
, me).data(
"indata"
, def.inputDate).data(
"onReturn"
, def.onReturn);
//調用規則,返回可選的日期範圍
if
(def.applyrule && $.isFunction(def.applyrule)) {
var
rule = def.applyrule.call(obj, obj[0].id);
if
(rule) {
if
(rule.startdate) {
cp.data(
"ads"
, rule.startdate);
}
else
{
cp.removeData(
"ads"
);
}
if
(rule.enddate) {
cp.data(
"ade"
, rule.enddate);
}
else
{
cp.removeData(
"ade"
);
}
}
}
else
{
//不存在則刪除限制
cp.removeData(
"ads"
).removeData(
"ade"
)
}
//畫月日曆內容td了
writecb();
$(
"#BBIT-DP-T"
).height(cp.height());
//獲取顯示依附的對象
var
t = def.showtarget || obj;
//獲取對象的位置
var
pos = t.offset();
//獲取對象的高度
var
height = t.outerHeight();
//日期選擇框的位置是依附對象的位置加上自己高度
var
newpos = { left: pos.left, top: pos.top + height };
//如下都是處理窗口邊界問題
var
w = cp.width();
var
h = cp.height();
var
bw = document.documentElement.clientWidth;
var
bh = document.documentElement.clientHeight;
if
((newpos.left + w) >= bw) {
newpos.left = bw - w - 2;
}
if
((newpos.top + h) >= bh) {
newpos.top = pos.top - h - 2;
}
if
(newpos.left < 0) {
newpos.left = 10;
}
if
(newpos.top < 0) {
newpos.top = 10;
}
//強制默認是月日期視圖
$(
"#BBIT-DP-MP"
).hide();
newpos.visibility =
"visible"
;
cp.css(newpos);
//移動到對應位置並顯示
$(
this
).attr(
"isshow"
,
"1"
);
//給document註冊單次的click事件,解決打開日期選擇器後,點擊其餘位置,隱藏日期選擇器的問題
$(document).one(
"click"
,
function
(e) {
me.attr(
"isshow"
,
"0"
);
cp.removeData(
"ctarget"
).removeData(
"cpk"
).removeData(
"indata"
);
cp.css(
"visibility"
,
"hidden"
);
});
return
false
;
//組織冒泡
}
|
其餘一些代碼都是日期操做的函數,如上月下月等就不作介紹了,你們若是對代碼上又任何問題均可以留言,我必定解答,最後是示例了
第一個示例是老老實實的演示Demo示例,有三種方式,也有調用方式的說明:
http://jscs.cloudapp.net/ControlsSample/dpdemo
第二個示例是我寫的日程管理控件中結合datepicker的應用(你們能夠先看看這個)
是datepicker在個人創造中的應用,最後若是你以爲這邊文章對你有所幫助,那就點擊一下【推薦】
本文的地址:http://www.cnblogs.com/xuanye/archive/2009/10/27/1590992.html
轉載請保留上面的連接,謝謝