使用纯原生JS实现日历

废话不多说,该有的注释都在代码里了;直接上代码:

HTML:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>促销日历</title>

    <!-- Bootstrap -->
    <link href="../static/js/bootstarp/css/bootstrap.min.css" rel="stylesheet">
    <link href="../static/icon/iconfont.css" rel="stylesheet">
    <script src="../static/js/jquery/jquery-3.4.1.min.js"></script>
    <script src="../static/js/bootstarp/js/bootstrap.min.js"></script>
</head>
<style>
    /*标题样式*/
    .title_div {
        padding-top: 8px;
        padding-bottom: 8px;
        border-bottom: #8c8c8c 1px solid;
    }

    .title_div_div {
        text-align: center;
        font-size: 20px;
    }

    /*当前日期*/
    .now_time {
        background-color: #FFEBF0;
        padding-top: 10px;
        padding-bottom: 10px;
        text-align: center;
    }

    /*日历样式*/
    .calendar {
        padding: 10px;
        background-color: #E9E9E9;
    }

    /*当前月份*/
    .month_year {
        font-size: 18px;
        background-color: #F3F3F3;
        text-align: center;
        padding-top: 5px;
        padding-bottom: 5px;
    }

    /*星期*/
    .week {
        background-color: #CACACA;
        padding: 7px;
        text-align: center;
    }

    /*单个日期的样式 取代除以七除不尽的问题*/
    .single_seven {
        width: 14.28571428%;
        float: left;
    }

    .day {
        border-right: #DCDCDC 1px solid;
    }

    /*日期的样式*/
    .single_day {
        border-bottom: #DCDCDC 1px solid;
        border-left: #DCDCDC 1px solid;
        text-align: left;
        background-color: #ffffff;
        padding-bottom: 15px;
    }

    /*促销列表标题*/
    .promotion_title {
        padding-top: 5px;
        padding-bottom: 5px;
        border-bottom: #8c8c8c 1px solid;
    }

    /*返回按钮*/
    .back_btn {
        font-size: 25px;
    }

    /*粉色按钮*/
    .pink_font {
        color: #FF92AD;
    }

    /*没有促销信息的*/
    .no_promotion_icon {
        font-size: 50px;
    }

    /*今天样式*/
    .today_div {
        background-color: #FFEEDE;
    }
</style>
<body>
<div class="container-fluid">
    <!-- 标题 -->
    <div class="row title_div">
        <div class="col-xs-2">
            <span class="iconfont back_btn">&#xe602;</span>
        </div>
        <div class="col-xs-10 title_div_div">
            <span>
                门店促销日历
            </span>
        </div>
    </div>
    <!-- 当前时间 -->
    <div class="row now_time">
        <div class="col-xs-6">
            <span class="iconfont pink_font">&#xe627;</span>
            <span id="today_day"></span>
        </div>
        <div class="col-xs-6" id="go_back_today">
            <span class="iconfont pink_font">&#xe624;</span> 回今天
        </div>
    </div>
    <!-- 日历 -->
    <div class="row calendar ">
        <div class="col-xs-12">
            <!-- 当前月 -->
            <div class="row month_year">
                <div class="col-xs-4" id='show_last_month'>
                    <span class="iconfont">&#xe602;</span>
                </div>
                <div class="col-xs-4">
                    <span id="current_month"></span>
                </div>
                <div class="col-xs-4" id='show_next_month'>
                    <span class="iconfont">&#xe608;</span>
                </div>
            </div>
            <!-- 星期 -->
            <div class="row week">
                <div class="single_seven"></div>
                <div class="single_seven"></div>
                <div class="single_seven"></div>
                <div class="single_seven"></div>
                <div class="single_seven"></div>
                <div class="single_seven"></div>
                <div class="single_seven"></div>
            </div>
            <!-- 日子 -->
            <div id="calendar_day"></div>
        </div>
    </div>
    <div class="row promotion_title">
        <div class="col-xs-12">
            <span><span class="iconfont pink_font">&#xe76a;</span> 促销列表</span>
        </div>
    </div>
    <div style="text-align: center">
        <span class="iconfont pink_font no_promotion_icon">&#xe614;</span>
        <br/>
        暂无数据
    </div>
</div>
</body>
<script src="../static/js/custom/promotion_calendar.js"></script>
</html>

JS:

/*是否是闰年*/
function leapYear(year) {
    /*
    维基百科闰年定义:
    公元年分除以4不可整除,为平年。
    公元年分除以4可整除但除以100不可整除,为闰年。
    公元年分除以100可整除但除以400不可整除,为平年。
    公元年分除以400可整除但除以3200不可整除,为闰年。
    */
    return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0 && year % 320 === 0);
}

/*获取一个月有多少天*/
function getMonthLength(year, month) {
    /*前七个月是偶数为小 奇数为大 二月比较特殊*/
    // 是否是二月
    if (month === 2) {
        // 是否是闰年
        if (leapYear(year)) {// 是闰年 二月只有28天
            return 28;
        } else {// 平年 二月有29天
            return 29;
        }
    }
    // 前七个月偶数是小月 后5个月偶数是大月
    if ((month < 8 && month % 2 === 0) || (month > 7 && month % 2 !== 0)) {// 小月
        return 30;
    } else {// 大月
        return 31;
    }
}

/*获取第一天是星期几*/
function getFistDayWeekInMonth(year, month) {
    // 获取当前时间对象
    let date = new Date();

    /*设置年份和月份*/
    //
    date.setFullYear(year);
    //
    date.setMonth(month - 1);
    //
    date.setDate(1);

    // 获取星期数
    return date.getDay() + 1;
}

/*设置日历*/
function setCalendar(year, month) {
    // 获取日历对象
    let calender = document.getElementById('calendar_day');
    // 移除所有的子节点
    calender.innerHTML = '';

    // 是否显示今天
    let now = new Date();
    let thisYear = now.getFullYear();
    let thisMonth = now.getMonth() + 1;
    let thisDay = now.getDate();
    let showToday = thisYear === year && month === thisMonth;

    // 常量
    const weeks = 6;
    const weekDay = 7;

    // 获取第一天星期几
    let fistDayWeek = getFistDayWeekInMonth(year, month);
    // 获取这月的长度
    let monthLength = getMonthLength(year, month);

    // 定义临时标签
    let weekDiv;
    let singleDayDiv;
    let singleDayDivText;
    let loopDay = -fistDayWeek + 2;

    for (let i = 0; i < weeks; i++) {
        // 创建外部Div
        weekDiv = document.createElement('div');
        // 添加样式
        weekDiv.className = 'row day';
        for (let j = 0; j < weekDay; j++) {
            /*如果是第一周 则要考虑 第一天星期几的问题*/
            if ((i === 0 && j < fistDayWeek - 1) || loopDay > monthLength) {// 添加空元素
                // 如果最后一周的第一天是空的 则退出循环
                if (i > 0 && j === 0) {
                    break;
                }
                singleDayDivText = document.createElement('br');
            } else {
                singleDayDivText = document.createTextNode(loopDay);
            }
            // 创建单天div
            singleDayDiv = document.createElement('div');
            // 添加文本内容
            singleDayDiv.appendChild(singleDayDivText);
            // 添加样式
            if (showToday && thisDay === loopDay) {
                singleDayDiv.className = 'single_seven single_day today_div';
            } else {
                singleDayDiv.className = 'single_seven single_day';
            }
            // 将生成的单天放到最外部的div中
            weekDiv.appendChild(singleDayDiv);
            // 将生成的div放到日历div中
            calender.appendChild(weekDiv);
            loopDay++;
        }
    }
}

/*上一个月*/
function showLastMonth() {
    // 获取文本内容
    let text = document.getElementById('current_month').innerHTML;
    // 获取年月
    let monthYearArray = text.split('月');
    let currentMonth = Number(monthYearArray[0]);
    let currentYear = Number(monthYearArray[1]);
    // 如果是1月 则要进入到去年的12月
    if (currentMonth === 1) {
        currentYear--;
        currentMonth = 12;
    } else {
        currentMonth--;
    }
    setCalendar(currentYear, currentMonth);
    // 设置月份显示
    document.getElementById('current_month').innerHTML = currentMonth + '月 ' + currentYear;
}

/*下一个月*/
function showNextMonth() {
    // 获取文本内容
    let text = document.getElementById('current_month').innerHTML;
    // 获取年月
    let monthYearArray = text.split('月');
    let currentMonth = Number(monthYearArray[0]);
    let currentYear = Number(monthYearArray[1]);
    // 如果是12月 则要进入到明年的1月
    if (currentMonth === 12) {
        currentYear++;
        currentMonth = 1;
    } else {
        currentMonth++;
    }
    setCalendar(currentYear, currentMonth);
    // 设置月份显示
    document.getElementById('current_month').innerHTML = currentMonth + '月 ' + currentYear;
}

// 给按钮添加事件
function addListen2Element() {
    // 上个月
    document.getElementById('show_last_month').addEventListener('click', showLastMonth);
    // 下个月
    document.getElementById('show_next_month').addEventListener('click', showNextMonth);
    // 回今天
    document.getElementById('go_back_today').addEventListener('click', goBackToday);
}

/*回到今天*/
function goBackToday() {
    // 获取文本内容
    let text = document.getElementById('current_month').innerHTML;
    // 获取年月
    let monthYearArray = text.split('月');
    let currentMonth = Number(monthYearArray[0]);
    let currentYear = Number(monthYearArray[1]);

    // 获取当前时间
    let now = new Date();
    // 获取当前年份
    let thisYear = now.getFullYear();
    // 获取当前月份
    let thisMonth = now.getMonth() + 1;

    // 如果当前时间和现在时间相同则不从新渲染
    if (thisYear === currentYear && thisMonth === currentMonth) {
        return;
    }
    setCalendar(thisYear, thisMonth);
    // 设置月份显示
    document.getElementById('current_month').innerHTML = thisMonth + '月 ' + thisYear;
}

/*本月日历*/
function setThisMonthCalendar() {
    // 获取当前时间对象
    let nowTime = new Date();
    // 获取年
    let year = nowTime.getFullYear();
    // 获取月
    let month = nowTime.getMonth() + 1;
    // 获取天
    let day = nowTime.getDate();

    // 开始渲染日历
    setCalendar(year, month,);
    // 设置月份显示
    document.getElementById('current_month').innerHTML = month + '月 ' + year;
    // 设置今天日期
    document.getElementById('today_day').innerHTML =
        year + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day) + ('(今天)');
}

window.onload = () => {
    // 给按钮添加事件
    addListen2Element();
    // 显示本月日历
    setThisMonthCalendar();
};

 

posted @ 2019-06-17 11:40  l48x4264l46  阅读(1911)  评论(0编辑  收藏  举报