前端---实现一个简单的日历

纯JS代码实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Calendar</title>
  <style>
    .calendar-container {
      padding: 30px;
      width: 576px;
    }

    .date-container {
      text-align: center;
      height: 50px;
      line-height: 50px;
    }

    /*上一月下一月按钮*/
    #preMonth,#nextMonth {
      position: relative;
    }
    #preMonth:after {
      content: '<';
      position: absolute;
      left: -28px;
      top: -1px;
      width: 24px;
      text-align: center;
      line-height: 24px;
      border-radius: 21px;
      background-color:brown;
      color: white;
    }
    #nextMonth:after {
      content: '>';
      position: absolute;
      left: 4px;
      top: -1px;
      width: 24px;
      text-align: center;
      line-height: 24px;
      border-radius: 21px;
      background-color:brown;
      color: white;
    }
    #nowYear,#nowMonth,#nowDate{
      padding: 0 5px;
    }


    .week-item {
      display: inline-block;
      width: 80px;
      height: 60px;
      line-height: 60px;
      border: 1px solid #EEEEEE;
      text-align: center;
    }

    .date-item {
      display: inline-block;
      width: 80px;
      line-height: 80px;
      border: 1px solid #EEEEEE;
      text-align: center;
    }
  </style>
</head>

<body>
  <div class="calendar-container">
    <div class="date-container">
      <span id="preMonth" class="year-prev"></span>
      <span id="nowYear" class="year-now"></span>
      <span id="nowMonth"></span>
      <span id="nowDate"></span>
      <span id="nextMonth" class="year-next"></span>
    </div>
    <div id="weekLine" class="week-line"></div>
    <div id="dateWrap" class="date-wrap"></div>
  </div>
</body>

</html>
<script>
  // 1.为了获得每个月的日期有多少,我们需要判断 平年闰年[四年一闰,百年不闰,四百年再闰]
  const isLeapYear = (year) => {
    return (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0);
  };
  // 2.获得每个月的日期有多少,注意 month - [0-11]
  const getMonthCount = (year, month) => {
    let arr = [
      31, null, 31, 30, 
      31, 30, 31, 31,
      30, 31, 30, 31
    ];
    let count = arr[month] || (isLeapYear(year) ? 29 : 28);
    return Array.from(new Array(count), (item, value) => value + 1);
  };
  // 3.获得某年某月的 1号 是星期几,这里要注意的是 JS 的 API-getDay() 是从 [日-六](0-6),返回 number
  const getWeekday = (year, month) => {
    let date = new Date(year, month, 1);
    return date.getDay();
  };
  // 4.获得上个月的天数
  const getPreMonthCount = (year, month) => {
    if (month === 0) {
      return getMonthCount(year - 1, 11);
    } else {
      return getMonthCount(year, month - 1);
    }
  };
  // 5.获得下个月的天数
  const getNextMonthCount = (year, month) => {
    if (month === 11) {
      return getMonthCount(year + 1, 0);
    } else {
      return getMonthCount(year, month + 1);
    }
  };
  // 工具方法 - end
  let weekStr = '日一二三四五六';
  weekArr = weekStr.split('').map(item => '星期' + item);
  // 插入星期 dom
  let weekDomStr = '';
  let oFragWeek = document.createDocumentFragment();
  weekArr.forEach(item => {
    let oSpan = document.createElement('span');
    let oText = document.createTextNode(item);
    oSpan.appendChild(oText);
    oSpan.classList.add('week-item');
    oFragWeek.appendChild(oSpan);
  });
  let weekWrap = document.getElementById('weekLine');
  weekWrap.appendChild(oFragWeek);

  // 这里获得第一次的 数据 数组
  const updateCalendar = (year, month, day) => {
    if (typeof year === 'undefined' && typeof month === 'undefined' && typeof day === 'undefined') {
      let nowDate = new Date();
      year = nowDate.getFullYear();
      month = nowDate.getMonth();
      day = nowDate.getDate();
    }
    // 更新一下顶部的年月显示
    document.getElementById('nowYear').innerHTML = year;
    document.getElementById('nowMonth').innerHTML = month + 1;
    document.getElementById('nowDate').innerHTML = day;
    // 生成日历数据,上个月剩下的的 x 天 + 当月的 28(平年的2月)或者29(闰年的2月)或者30或者31天 + 下个月的 y 天 = 42
    let res = [];
    let currentMonth = getMonthCount(year, month);
    let preMonth = getPreMonthCount(year, month);
    let nextMonth = getNextMonthCount(year, month);
    let whereMonday = getWeekday(year, month);
    if (whereMonday === 0) {
      whereMonday = 7
    }
    // 这里当 whereMonday 为 0 的时候会截取上月的所有数据
    let preArr = preMonth.slice(-1 * whereMonday)
    let nextArr = nextMonth.slice(0, 42 - currentMonth.length - whereMonday);
    res = [].concat(preArr, currentMonth, nextArr);
    // 更新 dom 的信息的问题
    let hadDom = document.getElementsByClassName('date-item');
    if (hadDom && hadDom.length) {
      let domArr = document.getElementsByClassName('date-item');
      for (let i = 0; i < domArr.length; i++) {
        domArr[i].innerHTML = res.shift();
      }
    } else {
      // 如果之前没有结构的话
      let str = '';
      for (let i = 0; i < 5; i++) {
        str += '<div class="date-line">';
        for (let j = 0; j < 7; j++) {
          str += `<span class='date-item'>${res.shift()}</span>`;
          if (j === 6) {
            str += '</div>';
          }
        }
      }
      document.getElementById('dateWrap').innerHTML = str;
    }
  };

  updateCalendar();
  // 添加上一月,下一月事件
  let oPreButton = document.getElementById('preMonth');
  let oNextButton = document.getElementById('nextMonth');
  oPreButton.addEventListener('click', function () {
    let currentYear = +document.getElementById('nowYear').textContent;
    let currentMonth = +document.getElementById('nowMonth').textContent - 1;
    let currentDate = +document.getElementById('nowDate').textContent;
    if (currentMonth === 0) {
      updateCalendar(currentYear - 1, 11, currentDate);
    } else {
      updateCalendar(currentYear, currentMonth - 1, currentDate);
    }
  });
  oNextButton.addEventListener('click', function () {
    let currentYear = +document.getElementById('nowYear').textContent;
    let currentMonth = +document.getElementById('nowMonth').textContent - 1;
    let currentDate = +document.getElementById('nowDate').textContent;
    if (currentMonth === 11) {
      updateCalendar(currentYear + 1, 0, currentDate);
    } else {
      updateCalendar(currentYear, currentMonth + 1, currentDate);
    }
  });
</script>

使用了Jquery

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Calendar</title>
  <style>
    .calendar-container {
      padding: 30px;
      width: 576px;
    }

    .date-container {
      text-align: center;
      height: 50px;
      line-height: 50px;
    }

    /*上一月下一月按钮*/
    #preMonth,#nextMonth {
      position: relative;
    }
    #preMonth:after {
      content: '<';
      position: absolute;
      left: -28px;
      top: -1px;
      width: 24px;
      text-align: center;
      line-height: 24px;
      border-radius: 21px;
      background-color:brown;
      color: white;
    }
    #nextMonth:after {
      content: '>';
      position: absolute;
      left: 4px;
      top: -1px;
      width: 24px;
      text-align: center;
      line-height: 24px;
      border-radius: 21px;
      background-color:brown;
      color: white;
    }
    #nowYear,#nowMonth,#nowDate{
      padding: 0 5px;
    }


    .week-item {
      display: inline-block;
      width: 80px;
      height: 60px;
      line-height: 60px;
      border: 1px solid #EEEEEE;
      text-align: center;
    }

    .date-item {
      display: inline-block;
      width: 80px;
      line-height: 80px;
      border: 1px solid #EEEEEE;
      text-align: center;
    }
  </style>
</head>

<body>
  <div class="calendar-container">
    <div class="date-container">
      <span id="preMonth" class="year-prev"></span>
      <span id="nowYear" class="year-now"></span>
      <span id="nowMonth"></span>
      <span id="nowDate"></span>
      <span id="nextMonth" class="year-next"></span>
    </div>
    <div id="weekLine" class="week-line"></div>
    <div id="dateWrap" class="date-wrap"></div>
  </div>
</body>

</html>
<!--JQuery-->
<script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>

<script>
  /**
    * 1.判断平年闰年[四年一闰,百年不闰,四百年再闰]
    */
  function isLeapYear(year) {
    return (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0);
  }


  /**
    * 2.获得每个月有几天,注意 month是[0-11]
    */
  function getMonthCount(year, month) {
    let arr = [
      31, null, 31, 30,
      31, 30, 31, 31,
      30, 31, 30, 31
    ];
    let count = arr[month] || (isLeapYear(year) ? 29 : 28);
    return Array.from(new Array(count), (item, value) => value + 1);
  }


  /**
    * 3.获得某年某月的 1号 是星期几,这里要注意的是 JS 的 API-getDay() 是从 [日-六](0-6),返回 number
    */
  function getWeekday(year, month) {
    let date = new Date(year, month, 1);
    return date.getDay();
  }

  /**
    * 4.获得上个月的天数
    */
  function getPreMonthCount(year, month) {
    if (month === 0) {
      return getMonthCount(year - 1, 11);
    } else {
      return getMonthCount(year, month - 1);
    }
  }



  /**
   * 5.获得下个月的天数
   */
  function getNextMonthCount(year, month) {
    if (month === 11) {
      return getMonthCount(year + 1, 0);
    } else {
      return getMonthCount(year, month + 1);
    }
  }




  // 工具方法 - end
  let weekStr = '日一二三四五六';
  weekArr = weekStr.split('').map(item => '星期' + item);
  // 插入星期 dom
  let weekDomStr = '';
  let oFragWeek = document.createDocumentFragment();
  weekArr.forEach(item => {
    let oSpan = document.createElement('span');
    let oText = document.createTextNode(item);
    oSpan.appendChild(oText);
    oSpan.classList.add('week-item');
    oFragWeek.appendChild(oSpan);
  });
  let weekWrap = document.getElementById('weekLine');
  weekWrap.appendChild(oFragWeek);


  // 这里获得第一次的 数据 数组
  const updateCalendar = (year, month, day) => {
    if (typeof year === 'undefined' && typeof month === 'undefined' && typeof day === 'undefined') {
      let nowDate = new Date();
      year = nowDate.getFullYear();
      month = nowDate.getMonth();
      day = nowDate.getDate();
    }
    // 更新一下顶部的年月显示
    document.getElementById('nowYear').innerHTML = year;
    document.getElementById('nowMonth').innerHTML = month + 1;
    document.getElementById('nowDate').innerHTML = day;
    // 生成日历数据,上个月剩下的的 x 天 + 当月的 28(平年的2月)或者29(闰年的2月)或者30或者31天 + 下个月的 y 天 = 42
    let res = [];
    let currentMonth = getMonthCount(year, month);
    let preMonth = getPreMonthCount(year, month);
    let nextMonth = getNextMonthCount(year, month);
    let whereMonday = getWeekday(year, month);
    if (whereMonday === 0) {
      whereMonday = 7
    }
    // 这里当 whereMonday 为 0 的时候会截取上月的所有数据
    let preArr = preMonth.slice(-1 * whereMonday)
    let nextArr = nextMonth.slice(0, 42 - currentMonth.length - whereMonday);
    res = [].concat(preArr, currentMonth, nextArr);
    // 更新 dom 的信息的问题
    let hadDom = document.getElementsByClassName('date-item');
    if (hadDom && hadDom.length) {
      let domArr = document.getElementsByClassName('date-item');
      for (let i = 0; i < domArr.length; i++) {
        domArr[i].innerHTML = res.shift();
      }
    } else {
      // 如果之前没有结构的话
      let str = '';
      for (let i = 0; i < 5; i++) {
        str += '<div class="date-line">';
        for (let j = 0; j < 7; j++) {
          str += `<span class='date-item'>${res.shift()}</span>`;
          if (j === 6) {
            str += '</div>';
          }
        }
      }
      document.getElementById('dateWrap').innerHTML = str;
    }
  };

  updateCalendar();


  // 点击上一月
  $('#preMonth').click(function () {
    let currentYear = $('#nowYear').html();         //年
    let currentMonth = $('#nowMonth').html() - 1;   //月
    let currentDate = document.getElementById('nowDate').textContent;
    if (currentMonth === 0) {
      updateCalendar(currentYear - 1, 11, currentDate);
    } else {
      updateCalendar(currentYear, currentMonth - 1, currentDate);
    }
  });

  // 点击下一月
  $('#nextMonth').click(function () {
    let currentYear = document.getElementById('nowYear').textContent;
    let currentMonth = document.getElementById('nowMonth').textContent - 1;
    let currentDate = document.getElementById('nowDate').textContent;
    if (currentMonth === 11) {
      updateCalendar(currentYear + 1, 0, currentDate);
    } else {
      updateCalendar(currentYear, currentMonth + 1, currentDate);
    }
  });
</script>

猜你喜欢

转载自blog.csdn.net/qq_39115469/article/details/106864080