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+Ajax实现用户名重名实时检测
Jun 01 jQuery
利用jquery去掉时光轴头尾部线条的方法实例
Jun 16 jQuery
js案例之鼠标跟随jquery版(实例讲解)
Jul 21 jQuery
jQuery的时间datetime控件在AngularJs中的使用实例(分享)
Aug 17 jQuery
JS和jQuery通过this获取html标签中的属性值(实例代码)
Sep 11 jQuery
jQuery实现右侧抽屉式在线客服功能
Dec 25 jQuery
jQuery+datatables插件实现ajax加载数据与增删改查功能示例
Apr 17 jQuery
JS与jQuery实现ListBox上移,下移,左移,右移操作功能示例
May 31 jQuery
jQuery+ajax实现批量删除功能完整示例
Jun 06 jQuery
如何使用CSS3+JQuery实现悬浮墙式菜单
Jun 18 jQuery
JavaScript前端页面搜索功能案例【基于jQuery】
Jul 10 jQuery
jquery实现掷骰子小游戏
Oct 24 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
提升PHP速度全攻略
2006/10/09 PHP
PHP 5.0 Pear安装方法
2006/12/06 PHP
Laravel 5框架学习之表单验证
2015/04/08 PHP
Yii2框架自定义验证规则操作示例
2019/02/08 PHP
简单的js分页脚本
2009/05/21 Javascript
子页向父页传值示例
2013/11/27 Javascript
JavaScript极简入门教程(一):基础篇
2014/10/25 Javascript
jQuery在页面加载时动态修改图片尺寸的方法
2015/03/20 Javascript
JavaScript实现动画打开半透明提示层的方法
2015/04/21 Javascript
angularjs在ng-repeat中使用ng-model遇到的问题
2016/01/21 Javascript
jQuery使用DataTable实现删除数据后重新加载功能
2017/02/27 Javascript
jQuery选取所有复选框被选中的值并用Ajax异步提交数据的实例
2017/08/04 jQuery
AngularJS与BootStrap模仿百度分页的示例代码
2018/05/23 Javascript
layer关闭弹出窗口触发表单提交问题的处理方法
2019/09/25 Javascript
微信小程序tabBar设置实例解析
2019/11/14 Javascript
JS图片预加载三种实现方法解析
2020/05/08 Javascript
[03:52]DOTA2英雄基础教程 酒仙
2013/12/23 DOTA
[11:42]2018DOTA2国际邀请赛寻真——OG卷土重来
2018/08/17 DOTA
python基于右递归解决八皇后问题的方法
2015/05/25 Python
Python中对象的引用与复制代码示例
2017/12/04 Python
Python  unittest单元测试框架的使用
2018/09/08 Python
从pandas一个单元格的字符串中提取字符串方式
2019/12/17 Python
Python实现Appium端口检测与释放的实现
2020/12/31 Python
10种CSS3实现的loading动画,挑一个走吧?
2020/11/16 HTML / CSS
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
护士毕业生自我鉴定
2014/02/08 职场文书
酒店行政人事部经理职务说明书
2014/02/26 职场文书
4s店活动策划方案
2014/08/25 职场文书
售后客服个人自我评价
2014/09/14 职场文书
小学班级管理心得体会
2016/01/07 职场文书
团队拓展训练心得体会
2016/01/12 职场文书
经销商会议开幕词
2016/03/04 职场文书
神州牡丹园的导游词
2019/11/20 职场文书
解决golang结构体tag编译错误的问题
2021/05/02 Golang
Python基础之数据类型知识汇总
2021/05/18 Python
Win11电脑显示本地时间与服务器时间不一致怎么解决?
2022/04/05 数码科技