新的产品需求需要,要写一个这样的日历插件。
效果图如下:
选择日期后,显示当前可以选择的时间,时间的列表是通过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://zxbcw.cn/post/201052/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)