jQuery实现可以扩展的日历


Posted in jQuery onDecember 01, 2020

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

效果图如下:

jQuery实现可以扩展的日历

选择日期后,显示当前可以选择的时间,时间的列表是通过ajax从后台获取的一组数据。
而且这个日期存在的情况,还是动态渲染的一个列表里面,再动态渲染的一个日历。

例如:

jQuery实现可以扩展的日历

此时的步骤图渲染是根据后台给的一个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";
   }

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

jQuery 相关文章推荐
jQuery EasyUI 组件加上“清除”功能实例详解
Apr 11 jQuery
使用jQuery,Angular实现登录界面验证码详解
Apr 27 jQuery
jQuery遮罩层实例讲解
May 11 jQuery
jQuery复合事件用法示例
Jun 10 jQuery
JQuery EasyUI的一些常用组件
Jul 12 jQuery
jQuery 实现鼠标画框并对框内数据选中的实例代码
Aug 29 jQuery
jquery+css3实现熊猫tv导航代码分享
Feb 12 jQuery
基于jQuery ztree实现表格风格的树状结构
Aug 31 jQuery
JQuery获取元素尺寸、位置及页面滚动事件应用示例
May 14 jQuery
JQuery发送ajax请求时中文乱码问题解决
Nov 14 jQuery
JQuery事件委托(适用于给动态生成的脚本元素添加事件)
Feb 01 jQuery
jQuery加PHP实现图片上传并提交的示例代码
Jul 16 jQuery
jQuery实现容器间的元素拖拽功能
Dec 01 #jQuery
jQuery实现查看图片功能
Dec 01 #jQuery
基于jQuery拖拽事件的封装
Nov 29 #jQuery
jQuery实现动态操作table行
Nov 23 #jQuery
jQuery-App输入框实现实时搜索
Nov 19 #jQuery
JQuery+drag.js上传图片并且实现图片拖曳
Nov 18 #jQuery
JavaScript枚举选择jquery插件代码实例
Nov 17 #jQuery
You might like
一个可以删除字符串中HTML标记的PHP函数
2006/10/09 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
使用PHP+MySql+Ajax+jQuery实现省市区三级联动功能示例
2017/09/15 PHP
php文件上传原理与实现方法详解
2019/12/20 PHP
TNC vs IO BO3 第二场2.13
2021/03/10 DOTA
js中eval详解
2012/03/30 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
Javascript 函数parseInt()转换时出现bug问题
2014/05/20 Javascript
基于jQuery实现的文字按钮表单特效整理
2014/12/07 Javascript
PHPExcel中的一些常用方法汇总
2015/01/23 Javascript
JQuery实现简单的服务器轮询效果实例
2016/03/31 Javascript
JS+CSS实现闪烁字体效果代码
2016/04/05 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
JS异步文件分片断点上传的实现思路
2016/12/25 Javascript
移动端刮刮乐的实现方式(js+HTML5)
2017/03/23 Javascript
angular.fromJson与toJson方法用法示例
2017/05/17 Javascript
bootstrap模态框远程示例代码分享
2017/05/22 Javascript
迅速了解一下ES10中Object.fromEntries的用法使用
2019/03/05 Javascript
Vue.js组件props数据验证实现详解
2019/10/19 Javascript
vue 监听 Treeselect 选择项的改变操作
2020/08/31 Javascript
python搭建简易服务器分析与实现
2012/12/15 Python
PyCharm设置SSH远程调试的方法
2018/07/17 Python
numpy.random模块用法总结
2019/05/27 Python
Python通过4种方式实现进程数据通信
2020/03/12 Python
python实现3D地图可视化
2020/03/25 Python
初中考试作弊检讨书
2014/02/01 职场文书
趣味体育活动方案
2014/02/08 职场文书
安全教育实施方案
2014/03/02 职场文书
模具设计与制造专业求职信
2014/07/19 职场文书
安全标兵事迹材料
2014/08/17 职场文书
2016年学校“6﹒26国际禁毒日”宣传活动总结
2016/04/05 职场文书
django上传文件的三种方式
2021/04/29 Python
详解CSS3.0(Cascading Style Sheet) 层叠级联样式表
2021/07/16 HTML / CSS
python代码实现备忘录案例讲解
2021/07/26 Python
MySQL数据库查询之多表查询总结
2022/08/05 MySQL