JS工具库moment —— 实现日历

moment

moment是一个js工具库,这个库中封装的是日期时间的方法,功能很全面。可以去moment官网看看,它的中文文档介绍的也很详细,主要是看一下方法的使用。附上官网地址:moment.js官网
JS工具库moment —— 实现日历_第1张图片

日历案例

模仿的是win10自带的日历,但是功能没有很全面,简单的实现了上下翻更新的效果,选择年份的功能没有实现呢。
简单说下,日历的逻辑问题。
从当前月出发,必须直到当前月的天数,必须知道当前月第一天是星期几。
只有知道了天数和第一天是星期几,才能知道第一天的位置在哪,要显示几天。核心点就是解决这两点,在解决了天数和星期的问题之后,当前月减去1就是上个月,当前月加上1就是下个月。那整体效果就出来了。
获取某月的天数,获取某月第一天是周几等等,moment已经为我们封装好了这些方法,直接使用就可以了。

案例中需要使用的方法

以下方法都是在moment()返回对象身上的方法
获取当前日期和时间:moment()
获取某月的天数:daysInMonth()
获取某月的第一天:startOf(‘month’)
获取某天是星期几:weekday()
增加时间:add(Number, String)
减去时间:subtract(Number, String)
设置中文的语言环境:locale(‘zh-ch’)
获取星期数据:weekdaysMin()
显示格式:format()。这个是使用最多用处最大的方法,它的参数是令牌,令牌不同日期和时间显示不同。

案例效果

JS工具库moment —— 实现日历_第2张图片

案例整体的功能分布

  • 即时的时间
  • 即时的日期
  • 获取星期
  • 生成日历
  • 日历对应的农历

结构和样式的话比较好搭,最终显示的部分都是通过js部分渲染出来的,就不做解释,后面会把代码附上。

  1. 即时的时间
    获取当下的时间,设置定时器每1S执行一次。
//中文语言环境
moment.locale('zh-cn');
// 一、即时的时间
function nowTime() {
    timeDate.innerHTML = moment().format('LTS');
}
nowTime();
setInterval(nowTime, 1000);
  1. 即时的日期
    这里牵扯到的还有农历日期,放到后面再补充
timeDay.innerHTML = moment().format("LL")
  1. 获取星期
    获取星期的数据,遍历添加结构,渲染视图。
// 二、星期
let weekArr = moment.weekdaysMin(true); // 根据语言环境获取不同的星期数组
let weekStr = '';
weekArr.forEach(function (ele) {
    weekStr += `${ele}`;
});
week.innerHTML = weekStr;
  1. 获取某月的天数以及某月第一天是周几
    封装两个方法,用来获取月的天数和第一天星期几,方法的参数都是moment对象。
// 日历逻辑:
// 必须知道当前月的天数,当前月第一天星期几
// 某月的天数
function getMonthDays(momentObj) {
    return momentObj.daysInMonth();
}
// console.log(getMonthDays(moment())); // 当前月最后一天的数字  
// console.log(getMonthDays(moment().subtract(1, 'month'))); // 当前月的上一个月最后一天的数字
// console.log(getMonthDays(moment().add(1, 'month'))); // 当前月的下一个月最后一天的数字


// 某月第一天的星期
// startOf 第一天
// weekday 星期几
function getWeekDays(momentObj) {
    return momentObj.startOf('month').weekday(); // 
}
// console.log(getWeekDays(moment())); // 当月
// console.log(getWeekDays(moment().add(1, 'month'))); // 下个月
  1. 生成日历
// 三、生成日历
let today = moment();
setDate(today);

封装生成日历方法
首先获取当前月的天数,当前月第一天是周几。英文环境下:[“Su”, “Mo”, “Tu”, “We”, “Th”, “Fr”, “Sa”];中文环境下:[“一”, “二”, “三”, “日”, “五”, “六”, “日”]。
获取周几返回的是数组的索引。

  • 上一个月:上个月在本月显示的天数 刚好等于获取星期得到的天数;
  • 下一个月:下月在本月显示的天数是出去当前月天数+上月显示天数剩余的天数;
  • 当前月:获取天数,同时要判断当月当天突出显示。
function setDate(m) {
    // 获得当前月的天数  和 第一天的星期数
    let curDays = getMonthDays(m); // 当前天数
    let curWeek = getWeekDays(m.clone()); // 当前月第一天的星期(索引值)
    let upDays = getMonthDays(m.clone().subtract(1, 'month')); // 上月的天数
    // console.log(curDays, curWeek, upDays);

    // 生成的结构
    let strDate = '';
    // 下个月的起始日期
    let nextFirstDate = 0;
    for (let i = 0; i < 42; i++) {
        // 1. 当前月的上一个月
        if (i < curWeek) { // 返回的索引值刚好是上月在当月显示的天数
            strDate = `
            
  • ${upDays}
  • ${strDate}`
    ; upDays--; // 倒叙显示 30 31 } else if (i >= curDays + curWeek) { //去除掉当月天数+上月天数就是下月天数 // 2. 当前月的下一个月:除去当月最后一天+上月的几天剩余的是下月开始计算 // curWeek 返回值刚好是上月占用的天数 nextFirstDate++; strDate += `
  • ${nextFirstDate}
  • `
    ; } else { // 3. 当前月 // i-curWeek+1 为当前月的天数 // date()获取日期号 // m.date() == i - curWeek + 1说明这一天是当月当天,添加样式 let currentClass = m.date() == i - curWeek + 1 ? 'current' : ''; if (m.year() != moment().year() || m.month() != moment().month()) { currentClass = ''; } strDate += `
  • ${currentClass}> ${i-curWeek+1}
  • `
    ; } } timeYM.innerHTML = m.format("YYYY年MMM"); // 更新日历头部的年月 dateList.innerHTML = strDate; // 渲染日历 }
    1. 上下翻页功能
      向上是上个月,向下是下个月。核心点就是添加和删除一个月份
    // 四、按钮事件
    upBtn.onclick = function () {
        // 点击切换为上个月
        setDate(today.subtract(1, 'month'));
    }
    
    downBtn.onclick = function () {
        // 点击切换为下个月
        setDate(today.add(1, 'month'));
    }
    
    1. 生成农历
      农历也是用到一个库文件:calendar.js,这个文件就是转换公历、阴历的。
      这里封装一个方法,通过公历获取对应的阴历日期
    //获取农历
    // 参数:年 月 日
    function getDayCn(year, month, date) {
    	// 把calendar文件中的calendar对象挂在了window对象上,通过属性调用calendar
    	// 这样不会更改源文件
        let dayCn = window.calendar.solar2lunar(year, month, date);
        let result = '';
    
        if (dayCn.IDayCn == '初一') { //如果是月初的话,换成这个月的名字
            result = dayCn.IMonthCn;
        } else if (dayCn.Term) { //如果有节气的话,换成节气
            result = dayCn.Term;
        } else if (dayCn.festival) { //如果有节日的话,换成节日
            result = dayCn.festival;
        } else if (dayCn.lunarFestival) { //如果有中国传统的节日的话,换成传统节日(春节、元宵节、端午节)
            result = dayCn.lunarFestival;
        } else {
            result = dayCn.IDayCn; //都没有的话就是农历
        }
        return result;
    }
    

    修改时间下面的日期,也就是加上农历日期

    // 即时的日期
    var dayCn = window.calendar.solar2lunar(moment().year(), moment().month() + 1,
        moment().date()); //取到农历日期
    // 拼接农历日期
    timeDay.innerHTML = moment().format("LL") +
        ' ' + dayCn.IMonthCn + dayCn.IDayCn + ' ' + (dayCn.Term ? dayCn.Term : ''); // 年月
    
    

    添加日历中对应的农历日期,这里我只把不同月拼接字符串的部分放上。

    注意:moment().month()返回值比实际月小1,比如本月是7月,moment().month()返回6,刚好是上月,moment().month()+1是本月,moment().month()+2是下月。

    // 1. 当前月的上一个月
            if (i < curWeek) {
            // 上月 getDayCn(m.year(),m.month(),upDays)
            // m.month()返回值与实际值少1
                strDate = `
                
  • ${upDays} ${getDayCn(m.year(),m.month(),upDays)}
  • ${strDate}`
    ; upDays--; } else if (i >= curDays + curWeek) { // 31+2=33 // 2. 当前月的下一个月:除去当月最后一天+上月的几天剩余的是下月开始计算 // curWeek 返回值刚好是上月占用的天数 strDate += `
  • ${nextFirstDate} ${getDayCn(m.year(),m.month()+2,nextFirstDate)}
  • `
    ; nextFirstDate++; } else { // 3. 当前月 // i-curWeek+1 为当前月的天数 let currentClass = m.date() == i - curWeek + 1 ? 'current' : ''; if (m.year() != moment().year() || m.month() != moment().month()) { currentClass = ''; } strDate += `
  • ${currentClass}> ${i-curWeek+1} ${getDayCn(m.year(),m.month()+1,i-curWeek+1)}
  • `
    ;

    到此,整个日历就完成了。其实用原生js也可以写,但是比较麻烦,使用js工具库写就相对比较简单了。整个日历的核心逻辑就是天数跟第一天是星期几,解决了这个核心点,日历的问题就解决了。
    在没写之前确实决定很难实现,在了解之后,明白了日历的逻辑,实现起来就好多了。
    加油!!!!

    日历代码

    结构

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>日历</title>
        <link rel="stylesheet" href="./index.css">
    </head>
    
    <body>
        <div class="calenderBox">
            <div class="title">
                <p class="timeHMS">10:18:06</p>
                <p class="timeYMD">2020729日 六月初九</p>
            </div>
            <div class="content">
                <div class="control">
                    <div class="timeYM">20207</div>
                    <div class="arrow">
                        <span class="up"></span>
                        <span class="down"></span>
                    </div>
                </div>
                <div class="dateList">
                    <div class="week">
                        <!-- <span></span>
                        <span></span> 
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span> -->
                    </div>
                    <ul>
                        <!-- <li><span>28</span><span>初八</span></li>
                        <li class="speical"><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li class="current"><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li>
                        <li><span>28</span><span>初八</span></li> -->
                    </ul>
                </div>
    
            </div>
        </div>
    
        <script src="./js/moment-with-locales.js"></script>
        <script src="./js/calendar.js"></script>
        <script src="./js/index.js"></script>
    </body>
    
    </html>
    

    样式:

    * {
        margin: 0;
        padding: 0;
    }
    
    body {
        background: #333;
        margin: 0;
    }
    
    ul {
        margin: 0;
        padding: 0;
        list-style: none;
    }
    
    .calenderBox {
        width: 420px;
        margin: 100px auto 0;
        border: 1px solid #444;
        background-color: #2d2d2d;
    }
    
    /* title */
    .title {
        padding: 20px 35px;
        border-bottom: 1px solid #535353;
    }
    
    .title .timeHMS {
        font-size: 40px;
        color: #efefef;
    }
    
    .title .timeYMD {
        font-size: 14px;
        color: #999;
    }
    
    /* content */
    .content {
        color: #efefef;
        padding: 20px 0;
    }
    
    .control {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0 35px;
        height: 25px;
        margin-bottom: 15px;
        /* border: 1px solid red;
        box-sizing: border-box; */
    }
    
    .arrow {
        padding-right: 5px;
    }
    
    .control .up,
    .control .down {
        display: inline-block;
        transform: scaleX(1.7);
        font-size: 20px;
        margin-left: 33px;
        cursor: pointer;
    }
    
    .dateList {
        padding: 0 20px;
    }
    
    .week {
        display: flex;
    }
    
    .week span {
        height: 40px;
        flex: 1 1 auto;
        text-align: center;
    }
    
    .dateList ul {
        display: flex;
        flex-wrap: wrap;
    }
    
    .dateList ul li {
        width: 54px;
        height: 54px;
        text-align: center;
    
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    
    .dateList ul li span:nth-child(2) {
        font-size: 14px;
    }
    
    .dateList li.speical {
        color: #6e6e6e;
    }
    
    .dateList li.current {
        background-color: #0078d7;
    }
    

    你可能感兴趣的:(JS工具类,日历,flex布局,moment)