新的产品需求需要,要写一个这样的日历插件。
效果图如下:
选择日期后,显示当前可以选择的时间,时间的列表是通过ajax从后台获取的一组数据。
而且这个日期存在的情况,还是动态渲染的一个列表里面,再动态渲染的一个日历。
例如:
此时的步骤图渲染是根据后台给的一个list来渲染的,所以,里面的元素但凡要点击,要交互,就要注意事件冒泡。
bootstrap的日历插件,运用起来也没法满足需求,所以*自己写了一个日历
代码如下:
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
|
var date = new Date()
var nowYear = date.getFullYear(); //获取当前年份
var nowMonth = date.getMonth() + 1; //获取当前月份
var nowDay = date.getDate(); //获取当前天
var splitString = "-" ; //年月日之间的分隔符
var weekDays = new Array( "日" , "一" , "二" , "三" , "四" , "五" , "六" ); //星期数组
var months = new Array( "一月" , "二月" , "三月" , "四月" , "五月" , "六月" , "七月" , "八月" , "九月" , "十月" , "十一月" , "十二月" ); //月份数组
var lastDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); //每个月的最后一天是几号
//变量保存,存储当前选择的年月
var checkYear = nowYear;
var checkMonth = nowMonth;
// //将选择的日期添加到输入框
function setInput(selectDay) {
$( '#txt_calendar' ).value = checkYear + splitString + checkMonth + splitString + selectDay;
hidDate();
}
// //显示控件
function showDate() {
createDate(nowYear, nowMonth); //创建日历
console.log(nowYear, nowMonth, '创建时间日历' )
//计算显示控件位置
///获取当前输入框的位置,在实际操作中需要修改此处ID
var x = $( '#txt_calendar' ).offset().left
var y = $( '#txt_calendar' ).offset().top + 22
console.log(x, y, 'x, y' , $( '#txt_calendar' ))
$( '#testID' ).css({
left: '-38px' ,
top: '37px'
})
}
// /*
// * 以下拼接日历框
// * 并定位日历框
// * */
// //创建日历样式
function createDate(thisYear, thisMonth) {
console.log(thisYear, thisMonth, '创建日历------------------' )
var createDoc = '<div style="height: 30px;">' ;
//当前年月日,点击此处日历自动跳到当前日期
createDoc += '<p style="width: 100%;height: 30px;text-align: center;color: #999; display: none;" onclick="getThisDay()">当前日期 ' + nowYear + "年" + nowMonth + "月" + nowDay + "号" ;
//关闭日历显示
createDoc += '<span id="closeDate" onClick="hidDate()" style="float: right;font-size: 25px;margin: -20px 3px 0 0;cursor: pointer;">×</span></p></div>' ;;
createDoc += '<div style="margin-bottom: 8px;">' ;
// 上月
createDoc += '<span id="lastMonth" style="margin: 0 20px 0 25px;cursor:pointer;"><</span>' ;
//创建年份下拉框[1900-2099]年onchange="changeYearAndMonth()">
createDoc += '<select id ="selectYear" class="selectStyle"' ;
for ( var y = 1900; y <= 2099; y++) {
createDoc += "<option value=" + y + ">" + y + "</option>" ;
}
createDoc += "</select>年" ;
//创建月份下拉框onchange="changeYearAndMonth()">
createDoc += '<select id ="selectMonth" style="overflow: auto;" class="selectStyle"' ;
for ( var m = 0; m <= 12; m++) {
createDoc += `<option style= 'z-index: 9999;' value= "${m}" >${m}</option>`;
}
createDoc += "</select>月" ;
//下一月 onClick="nextMonthClick()"
createDoc += '<span id="nextMonth"style="float: right;margin-right: 25px;cursor:pointer; padding-left: 10px;">></span></div>' ;
//创建星期
createDoc += '<div class="everyWeekDay">' ;
for ( var i = 0; i < weekDays.length; i++) {
if (weekDays[i] == "日" || weekDays[i] == "六" ) {
createDoc += `<span class= "weekday" style= "background-color: #18bc9c;color:#ccc;" >${weekDays[i]}</span>`
} else {
createDoc += `<span style= "background-color: #18bc9c;color:#fff;" class= "weekday" >${weekDays[i]}</span>`
}
}
createDoc += '</div>' ;
//创建每月天数
createDoc += '<div class="everyDay"><div class="marginTop">' ; //日期样式DIV
var thisWeek = getThisWeekDay(thisYear, thisMonth, 1); //算出当前年月1号是星期几
/*$(this).css({ 'cursor': 'no-drop' })
* 如果当前不是星期天,创建空白日期占位
* 若是星期天,则循环输出当月天数
* 待修改优化,后期改为变色的前一个月日期
*/
if (thisWeek != 0) {
for ( var i = 0; i < thisWeek; i++) {
createDoc += '<span class="days"></span>' ;
}
}
//循环输出当月天
//getThisMonthDay()获取当月天数
for ( var i = 1; i < getThisMonthDay(thisYear, thisMonth) + 1; i++) {
// if (thisYear == nowYear && thisMonth == nowMonth && i == nowDay) {
// //今天的显示
// if (getThisWeekDay(thisYear, thisMonth, i) == 6 || getThisWeekDay(thisYear, thisMonth, i) == 0) {
// //今天是周末
// createDoc += '<span class="days anyDay" data- style="background-color:#4eccc4;color:#FFFFFF;cursor:pointer;">' + i + '</span>';
// } else {
// createDoc += '<span class="days anyDay" style="background-color:#4eccc4;color:#FFFFFF;cursor:pointer;">' + i + '</span>';
// }
// } else {
// 不可选择的变成灰色, 目前是周末变成灰色
// if (getThisWeekDay(thisYear, thisMonth, i) == 6 || getThisWeekDay(thisYear, thisMonth, i) == 0) {
// // onClick="setInput(' + i + ')"
// createDoc += '<span id="weekends" class="days anyDay"" style="color:#ccc; cursor:pointer;">' + i + '</span>';
// } else {
// console.log(nowDay, 'nowDay-------------')
if (i == nowDay) {
createDoc += `<div class="days anyDay " data-date=" ${thisYear}-${thisMonth}-${i} " style=" cursor:pointer;background-color: #4eccc4;color:#FFFFFF;">${i}<div class="timeList">`;
} else {
createDoc += `<div class="days anyDay " data-date=" ${thisYear}-${thisMonth}-${i} " style=" cursor:pointer; ">${i}<div class=" timeList ">`;
}
let weeknum = getThisWeekDay(thisYear, thisMonth, i)
let weektext = '周' + weekDays[weeknum]
for (let _i = 0; _i < interviewtimelist.length; _i++) {
if (weeknum == interviewtimelist[_i].week) {
createDoc += `<p class='interViewTime' style=" width: 100%; border-bottom: 1px solid #ccc;" data-week="${interviewtimelist[_i].week}" data-time="${interviewtimelist[_i].time}" data-amorpm="${interviewtimelist[_i].amorpm}">${weektext} ${interviewtimelist[_i].amorpm} ${interviewtimelist[_i].time}</p>`
}
}
createDoc += '</div></div>'
// }
// }
//星期六换行
if (getThisWeekDay(thisYear, thisMonth, i) == 6) {
createDoc += "</tr> ";
}
}
createDoc += '</div></div>';
$('#testID').html(createDoc)
//将创建好的控件字符串添加到div中
//默认选择当前年份
console.log(thisMonth, '当前月份为-------------')
$('#selectYear').val(thisYear)
//默认选择当前月
$('#selectMonth').val(thisMonth)
if (thisMonth == 1) {
$('#selectMonth').val('1')
}
console.log(thisMonth, '当前月份为-------------', $('#selectMonth').val())
}//日历创建结束
// //跳转到当前日
function getThisDay() {
checkYear = nowYear;
checkMonth = nowMonth;
createDate(checkYear, checkMonth);
}
//上一个月
$(document).on('click', '#lastMonth', function (event) {
event.stopPropagation()
lastMonthClick()
})
function lastMonthClick() {
//若当前是1月份,年份减一,月份变为12
if (checkMonth == 1) {
checkYear = checkYear - 1;
checkMonth = 12;
} else {
checkMonth = checkMonth - 1;
}
//创建当前月份日期
createDate(checkYear, checkMonth);
}
//下一月
$(document).on('click', '#nextMonth', function (event) {
event.stopPropagation()
nextMonthClick()
})
function nextMonthClick() {
//若当前是12月份,年份加1,月份变为1
if (checkMonth == 12) {
checkYear = parseInt(checkYear + 1);
checkMonth = 1;
} else {
checkMonth = parseInt(checkMonth + 1);
}
//创建当前月份日期
createDate(checkYear, checkMonth);
}
//年月下拉框-年selectMonth
$(document).on('click', '.selectStyle', function (event) {
event.stopPropagation()
})
$(document).on('click', '.selectStyle option', function (event) {
event.stopPropagation()
})
// 点击年份
$(document).on('change', '#selectYear', function (event) {
event.stopPropagation()
changeYearAndMonth()
})
//年月下拉框-月
$(document).on('change', '#selectMonth', function (event) {
event.stopPropagation()
changeYearAndMonth()
})
function changeYearAndMonth() {
checkYear = $('#selectYear').val()
checkMonth = $('#selectMonth').val();
createDate(checkYear, checkMonth);
}
//判断是否为闰年
function isLeapYear(year) {
var isLeap = false;
if (0 == year % 4 && ((year % 100 != 0) || (year % 400 == 0))) {
//闰年可以被4整除且不能被100整除,或者能整除400
isLeap = true;
}
return isLeap;
}
//获取某月份的总天数
function getThisMonthDay(year, month) {
var thisDayCount = lastDays[month - 1]; //获取当前月份的天数
if ((month == 2) && isLeapYear(year)) {
//若当前月份为2月,并且是闰年,天数加1
thisDayCount++;
}
return thisDayCount;
}
//计算某天是星期几
function getThisWeekDay(year, month, date) {
//将年月日创建Date对象,返回当前星期几
var thisDate = new Date(year, month - 1, date);
return thisDate.getDay();
}
/**
*
* @param {*} curdate 鼠标滑过的日期
* @param {*} today 今天的日期
*/
function compareDate(curdate) {
let today = Date.parse(nowYear + '-' + nowMonth + '-' + nowDay)
let cur = Date.parse(curdate)
if (cur <= today) {
return false
} else {
return true
}
// var cur = curdate.split('-')
// var c = Date.parse(curdate)
}
$(document).on('mouseover', '.anyDay', function (event) {
event.stopPropagation()
console.log($(this).context.dataset.date)
let canclick = compareDate($(this).context.dataset.date) ? true : false
if ($(this).children().children().length <= 0 || !canclick) { // 不可点击的状态
$(this).css({ 'cursor': 'no-drop' })
$(this).siblings().children('.timeList').hide()
return
} else { // 可点击的状态
$(this).children('.timeList').show()
$(this).siblings().children('.timeList').hide()
}
})
$(document).on('click', '.anyDay', function (event) {
event.stopPropagation()
let canclick = compareDate($(this).context.dataset.date) ? true : false
curInterViewDate = $(this).context.dataset.date
if ($(this).children().children().length <= 0 || !canclick) { // 不可点击的状态
$(this).siblings().children('.timeList').hide()
return
} else { // 可点击的状态
$(this).children('.timeList').show()
$(this).siblings().children('.timeList').hide()
}
})
/**
* 点击选择当前时间var curClickStatus = ''
var curInterViewDate = ''
var curInterViewTime = ''
var curAmPm = ''
* 更新页面的显示,以及保存参数后续点击确定的时候,传给后台
*/
$(document).on('click', '.interViewTime', function (event) {
event.stopPropagation()
// curInterViewDate = $(this).context.dataset.
let week = '周' + weekDays[$(this).context.dataset.week]
curInterViewTime = $(this).context.dataset.time
curAmPm = $(this).context.dataset.amorpm
console.log($(this))
let text_input = week + ' ' + curInterViewDate + ' ' + curAmPm + ' ' + curInterViewTime
$('#txt_calendar').val(text_input)
$('#testID').hide()
})
/**
* 点击面试时间的元素。渲染到页面“请选择面试时间” “”
* 隐藏日历并恢复日历最初的值。
*
*/
$(document).on('click', '.anyDay', function (event) {
event.stopPropagation()
if ($(this).children().children().length <= 0) { // 不可点击的状态
$(this).css({ 'cursor': 'no-drop' })
return
} else { // 可点击的状态
$(this).children('.timeList').show()
$(this).siblings().children('.timeList').hide()
}
console.log(this, '点击当前元素----', $(this).children().children().length)
})
// //关闭日期选择框
function hidDate() {
$('#dateOuter').style.display = " none";
}
|
目前可以实现需求了,但还有很多的不足,如果有好的建议,欢迎留言哦~
原文链接:https://blog.csdn.net/shadow_yi_0416/article/details/108266422