欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js實現(xiàn)日歷

 更新時間:2020年11月07日 10:08:43   作者:??蜔o心x  
這篇文章主要介紹了js如何實現(xiàn)日歷,幫助大家完成需求,提高對js的理解,感興趣的朋友可以了解下

這周寫自己的項目發(fā)現(xiàn)又用到日歷了,加之自己畢業(yè)之后的第一個工作中遇到的任務(wù)也是需要寫個日歷(組員寫了,我就不用寫了)
今天就來好好折騰一下日歷是怎么寫的。

首先,我們看看 windows 的日歷。發(fā)現(xiàn)總共有這么幾個元素。先實現(xiàn)試試。

1.年份的選擇、月份的選擇
2.周一 ~ 周日(周日 ~ 周六)
3.日歷格子 6*7 = 42

從數(shù)據(jù)的角度來分析日歷的實現(xiàn)是比較簡單的
1.我們需要顯示一個當(dāng)前時間的結(jié)構(gòu) - new Date()
2.我們需要顯示當(dāng)月的信息 - [星期(周一~周日),日期(1-[28,29,30,31])]
其中我們只要知道了每個月的 1日 是星期幾,就能很容易地擺放后面的日子(萬事開頭難)。

  • 我們最多需要 6 行來顯示我們的日期,因為要第一排如果只包含本月的一天 6(上個月的) + (1 + 4*7),這樣就五行了,當(dāng)月天數(shù)若大于 29,就顯示不下了
  • 確定了 6 行之后,我們發(fā)現(xiàn)我們可能需要獲取上個月,和下個月多出來的幾天的擺放位置。
  • 不同年份的不同月的 2月份,我們知道它的日期是不同的,所以我們還需要判斷 平年還是閏年。

3.顯示上個月,下個月的切換。我們發(fā)現(xiàn)需要有個函數(shù)來幫我們更新日歷。

分析完之后,讓我們跟著 新增/修改 一些代碼。

<!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>Document</title>
<style>
 .week-item {
  display: inline-block;
  width: 80px;
  height: 40px;
  line-height: 40px;
  border: 1px solid sandybrown;
  text-align: center;
 }
 .date-item {
  display: inline-block;
  width: 80px;
  height: 40px;
  line-height: 40px;
  border: 1px solid beige;
  text-align: center;
 }
</style>
</head>
<body>
 <div class="wrapper">
  <div class="year-line">
   <button id="preMonth" class="year-prev">上一月</button>
   <button id="nowYear" class="year-now"></button>
   <button id="nowMonth"></button>
   <button id="nowDate"></button>
   <button id="nextMonth" class="year-next">下一月</button>
  </div>
  <div id="weekLine" class="week-line"></div>
  <div id="dateWrap" class="date-wrap"></div>
 </div>
</body>
<script>
 // 工具方法 - start
 // 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.獲得上個月的天數(shù)
 const getPreMonthCount = (year, month) => {
  if (month === 0) {
   return getMonthCount(year - 1, 11);
  } else {
   return getMonthCount(year, month - 1);
  }
 };
 // 5.獲得下個月的天數(shù)
 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);

 // 這里獲得我們第一次的 數(shù)據(jù) 數(shù)組
 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;
  // 生成日歷數(shù)據(jù),上個月剩下的的 x 天 + 當(dāng)月的 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
  }
  // 感謝網(wǎng)友 luoyiming 的測試(哈哈!謝謝?。哼@里當(dāng) whereMonday 為 0 的時候會截取上月的所有數(shù)據(jù)
  let preArr = preMonth.slice(-1 * whereMonday)
  let nextArr = nextMonth.slice(0, 42 - currentMonth.length - whereMonday);
  res = [].concat(preArr, currentMonth, nextArr);
  // 上面經(jīng)過我本人的測試是沒有什么問題,接下來就是更新 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 {
   // 如果之前沒有結(jié)構(gòu)的話
   let str = '';
   for (let i = 0; i < 6; 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>
</html>

發(fā)現(xiàn)用 dom 直接操作而不是通過 mvvm 框架實現(xiàn)確實還是比較蛋疼的,以下是這次實現(xiàn)的效果。

實現(xiàn)一個功能的時候,從數(shù)據(jù)的層面分析,有時候會比較容易理解

以上就是js實現(xiàn)日歷的詳細(xì)內(nèi)容,更多關(guān)于js 日歷的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • webpack HappyPack實戰(zhàn)詳解

    webpack HappyPack實戰(zhàn)詳解

    這篇文章主要介紹了webpack HappyPack實戰(zhàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 腳本吧 - 幻宇工作室用到j(luò)s,超強(qiáng)推薦expand.js

    腳本吧 - 幻宇工作室用到j(luò)s,超強(qiáng)推薦expand.js

    腳本吧 - 幻宇工作室用到j(luò)s,超強(qiáng)推薦expand.js...
    2006-12-12
  • IntersectionObserver API 詳解篇

    IntersectionObserver API 詳解篇

    這篇文章主要介紹了IntersectionObserver API 詳解篇,需要的朋友可以參考下
    2016-12-12
  • 關(guān)于ES6中數(shù)組新增的方法詳解

    關(guān)于ES6中數(shù)組新增的方法詳解

    數(shù)組(Array)是有序的元素序列,若將有限個類型相同的變量的集合命名,那么這個名稱為數(shù)組名,下面這篇文章主要給大家介紹了關(guān)于ES6中數(shù)組新增方法的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • JavaScript 預(yù)解析的4種實現(xiàn)方法解析

    JavaScript 預(yù)解析的4種實現(xiàn)方法解析

    這篇文章主要介紹了JavaScript 預(yù)解析的4種實現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09
  • 用javascript做拖動布局的思路

    用javascript做拖動布局的思路

    這幾天不是很忙,就找了些拖動布局方面的資料看看,也學(xué)著寫了個拖動布局的效果,沒想到花了好多時間, 七拼八湊,總算是把這個效果寫出來了。哎!還是js的功夫太差。因為是邊找資料邊寫的,很多地方印象不深, 時間一長,再重新寫估計也難,所以把當(dāng)時的思路記錄一下!也希望大蝦指點一下!
    2008-05-05
  • JS DOM 操作實現(xiàn)代碼

    JS DOM 操作實現(xiàn)代碼

    JS DOM 操作實現(xiàn)代碼,學(xué)習(xí)dom操作的朋友可以參考下。
    2010-08-08
  • JS數(shù)據(jù)類型(基本數(shù)據(jù)類型、引用數(shù)據(jù)類型)及堆和棧的區(qū)別分析

    JS數(shù)據(jù)類型(基本數(shù)據(jù)類型、引用數(shù)據(jù)類型)及堆和棧的區(qū)別分析

    這篇文章主要介紹了JS數(shù)據(jù)類型(基本數(shù)據(jù)類型、引用數(shù)據(jù)類型)及堆和棧的區(qū)別,結(jié)合實例形式分析了JS基本數(shù)據(jù)類型、引用數(shù)據(jù)類型概念、用法,以及堆和棧的區(qū)別,需要的朋友可以參考下
    2020-03-03
  • 詳解JS中定時器setInterval和setTImeout的this指向問題

    詳解JS中定時器setInterval和setTImeout的this指向問題

    在js中setTimeout和setInterval都是用來定時的一個功能,下面這篇文章主要給介紹了JS中setInterval和setTImeout的this指向問題,文中通過示例介紹的很詳細(xì),有需要的朋友可以參考借鑒,一起來看看吧。
    2017-01-01
  • js模擬實現(xiàn)百度搜索

    js模擬實現(xiàn)百度搜索

    這篇文章主要為大家詳細(xì)介紹了js模擬實現(xiàn)百度搜索,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06

最新評論