新的产品需求需要,要写一个这样的日历插件。

效果图如下:

jquery日期表单 jquery日历_日历


选择日期后,显示当前可以选择的时间,时间的列表是通过ajax从后台获取的一组数据。

而且这个日期存在的情况,还是动态渲染的一个列表里面,再动态渲染的一个日历。

例如:

jquery日期表单 jquery日历_日历_02


此时的步骤图渲染是根据后台给的一个list来渲染的,所以,里面的元素但凡要点击,要交互,就要注意事件冒泡。

bootstrap的日历插件,运用起来也没法满足需求,所以被迫自己写了一个日历

代码如下:

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";
            }

目前可以实现需求了,但还有很多的不足,如果有好的建议,欢迎留言哦~