1. 程式人生 > 其它 >Js動態生成日曆

Js動態生成日曆

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>日曆</title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
      }
      ol,
      ul,
      li {
        list-style: none;
      }
      :root {
        /* 定義變數 --變數名 通過var得到變數值 
			(1)  定義到根元素  => 頁面中都就可以使用
            (2)  定義到父元素  => 子元素可以使用*/
        --line-height: 40px;
      }
      .calendar {
        width: 300px;
        margin: 50px auto;
        background-color: aliceblue;
        padding: 10px;
      }
      .calendar-header {
        display: flex;
        justify-content: space-between;
        font-size: 14px;
        line-height: 40px;
      }
      .calendar-title {
        display: flex;
        justify-content: space-between;
        font-size: 14px;
        line-height: 40px;
      }
      .calendar .calendar-list {
        display: flex;
        flex-wrap: wrap;
        text-align: center;
        font-size: 14px;
        line-height: var(--line-height);
      }
      .calendar .calendar-list li {
        flex: 1;
        flex-basis: -webkit-calc(100% / 7);
        border: 1px solid transparent;
        box-sizing: border-box;
        color: black;
      }
      .calendar-list li:hover {
        border-color: dodgerblue;
      }

      .calendar .calendar-list .today {
        background-color: pink;
      }

      .calendar .calendar-list .prevMonth,
      .calendar .calendar-list .nextMonth {
        color: #666;
      }
      .calendar .calendar-list .thisMonth {
        color: black;
        font-weight: 500;
      }
    </style>
  </head>
  <body>
    <div class="calendar">
      <div class="calendar-header">
        <div class="calendar-prev">&lt;</div>
        <div class="calendar-date"></div>
        <div class="calendar-next">&gt;</div>
      </div>
      <ul class="calendar-title">
        <li>一</li>
        <li>二</li>
        <li>三</li>
        <li>四</li>
        <li>五</li>
        <li>六</li>
        <li>日</li>
      </ul>
      <ul class="calendar-list"></ul>
    </div>
  </body>
  <script type="text/javascript">
    var calendarDate = document.getElementsByClassName("calendar-date")[0]; //年份月份
    var calendarPrev = document.getElementsByClassName("calendar-prev")[0]; //上個月切換
    var calendarNext = document.getElementsByClassName("calendar-next")[0]; //下個月
    var calendarList = document.getElementsByClassName("calendar-list")[0]; //日曆主體
    var date = new Date(); //獲取當前時間 - 是一個全域性變數

    //日曆生成函式封裝
    function createCalendar() {
      //獲取當前的年份和月份並將年月內容顯示到指定的div中(日期展示)
      var year = date.getFullYear();
      var month = date.getMonth() + 1;
      calendarDate.textContent = year + "年" + month + "月";

      //日曆生成 - 相關資料獲取
      var week = getFirstDayWeek(date); //date找全域性
      week = week === 0 ? 7 : week; //如果獲取到的week為0說明是週日
      var lastMonthDays = getLastMonthDays(date);
      var thisMonthDays = getThisMonthDays(date);
      console.log(
        "本月第一天為周:",
        week,
        "上個月天數為:",
        lastMonthDays,
        "本月天數為:",
        thisMonthDays
      );
      //date:切換後的日期物件
      //now:今天的日期物件
      //如果切換後的date是今年 今月 今日 => 特殊樣式
      var now = new Date();
      var nowYear = now.getFullYear();
      var nowMonth = now.getMonth() + 1;
      var today = now.getDate();
      var html = "";
      //日曆生成 - 上個月模組生成
      //初始值i = 上個月天數-(當前月在第一行空餘位置)+1 => 遞增直至上個月最後一天
      for (var i = lastMonthDays - (week - 1) + 1; i <= lastMonthDays; i++) {
        //上個月有可能是當前月的上個月也可能是下個月的上個月(當前月)
        if (year == nowYear && month - 1 == nowMonth && i == today) {
          html += `<li class="prevMonth today">${i}</li>`;
        } else {
          html += `<li class="prevMonth">${i}</li>`;
        }
      }
      //日曆生成 - 本月模組生成
      for (var i = 1; i <= thisMonthDays; i++) {
        if (year == nowYear && month == nowMonth && i == today) {
          html += `<li class="thisMonth today">${i}</li>`;
          //輪到今天時多新增一個class
        } else {
          html += `<li class="thisMonth">${i}</li>`;
        }
      }
      //日曆生成 - 下個月模組生成
      //下個月從1開始,顯示到本月的終止天數為:42-(上個月所佔天數)-本月天數
      for (var i = 1; i <= 42 - (week - 1) - thisMonthDays; i++) {
        //下個月有可能是當前月的下個月也可能是上個月的上個月(當前月)
        if (year == nowYear && month + 1 == nowMonth && i == today) {
          html += `<li class="nextMonth today">${i}</li>`;
        } else {
          html += `<li class="nextMonth">${i}</li>`;
        }
      }
      //日曆生成 - 顯示到日曆列表元素中
      calendarList.innerHTML = html;
    }
    //呼叫函式生成本月的日曆頁
    createCalendar();
    //點選切換到上個月
    calendarPrev.onclick = function () {
      date.setDate(1); //將時間設定為本月第一天,date會受到影響但不會影響日曆生成
      date.setMonth(date.getMonth() - 1); //切到上個月
      //如果沒有將時間設為第一天直接切換月份可能會因為每月時間不同產生錯誤
      createCalendar();
    };
    //點選切換到下個月
    calendarNext.onclick = function () {
      date.setDate(1); //將時間設定為本月第一天,date會受到影響但不會影響日曆生成
      date.setMonth(date.getMonth() + 1); //切到下個月
      createCalendar();
    };

    //獲取某個月第一個是星期幾的函式(0-6)
    function getFirstDayWeek(date) {
      date = new Date(date); //先獲取當前日期
      date.setDate(1); //將天數設定為本月的第一天
      return date.getDay(); //獲取第一天的星期(0-6)
    }
    //獲取上個月天數的函式
    function getLastMonthDays(date) {
      date = new Date(date);
      date.setDate(0); //設定日期為本月第0天即換算到上個月最後一天
      return date.getDate(); //獲取設定後的日期日份即為上個月天數
    }
    //獲取本月天數的函式
    function getThisMonthDays(date) {
      date = new Date(date);
      date.setDate(1); //設定當前時間為本月第一天
      date.setMonth(date.getMonth() + 1); //設定本月到下個月
      date.setDate(0); //設定時間為下個月第0天即本月最後一天
      return date.getDate(); //得到本月的天數
    }
  </script>
</html>

效果:

主要思路: