日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

JavaScript日历(es5版本)

發(fā)布時(shí)間:2025/6/16 javascript 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript日历(es5版本) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

近期在知乎上看到這么一個(gè)帖子,題主說(shuō)自己JavaScript都學(xué)完了,結(jié)果老師留的作業(yè)還是不會(huì)寫,就是寫一個(gè)日歷的插件,結(jié)果樓下一堆大牛出現(xiàn)了,百度的阿里的紛紛站出來(lái)發(fā)表自己的看法,有人認(rèn)為簡(jiǎn)單,有人認(rèn)為其實(shí)細(xì)化不簡(jiǎn)單,于是出于好奇,自己也來(lái)動(dòng)手寫了一下。雖說(shuō)現(xiàn)如今各種優(yōu)秀的UI框架層出不窮,都會(huì)自帶calendar和datepick這種日歷相關(guān)的組件,而且無(wú)論是適配還是視覺效果都做得相當(dāng)nice,可能都不會(huì)用到自己寫的,但是還是打算動(dòng)手,因?yàn)閐ate對(duì)象也是js里面的重點(diǎn)。

?

第一版:純js實(shí)現(xiàn)
通過(guò)切換月份和年份,來(lái)展示不同的日歷頁(yè)面,實(shí)際上是根據(jù)當(dāng)前年月,來(lái)進(jìn)行頁(yè)面的重繪,所以頁(yè)面渲染是一個(gè)函數(shù),所需參數(shù)就是當(dāng)前選中的年份和月份。
const render = (month, year) => {
};
render();
首先,日歷除去首行day有幾行? 一共6行,Math.ceil((31 - 1) / 7 + 1) = 6

三塊組成:上月剩余,本月,下月開始
1,上月剩余 首先要知道本月1號(hào)是周幾(x),然后從周日到x的天數(shù)就是上月剩余天數(shù),從幾號(hào)到幾號(hào),需要了解本月是幾月,來(lái)推算出上月月末是幾號(hào),其實(shí)也就是上月有多少天。
2,本月 只需知道當(dāng)月是幾月,當(dāng)月多少天,然后按順序排。
3,下月開始 只需要知道下月1號(hào)是周幾,然后42個(gè)數(shù)字還剩多少,從1排到最后就可以了 代碼部分: HTML: <!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>Date Picker</title><link rel="stylesheet" type="text/css" href="css/index.css"></link> </head> <body><input id="textInput" class="textInput" type="text" placeholder="選擇日期" /><div id="datePicker" class="datePicker datePickerHide"><div class="dateHeader"><span id="yearLeft" class="left headerMid"><<</span><span id="monthLeft" class="left headerMid page"><</span><span id="changeDateHead" class="page"><span id="changeYear" class="headerMid col"><span id="dateYear"></span><span>年</span></span><span id="changeMonth" class="headerMid col"><span id="dateMonth"></span><span>月</span></span></span><span id="changeYearHead" class="page headerMid col" style="display: none"><span id="changeYearFirst"></span><span>年</span><span>-</span><span id="changeYearLast"></span><span>年</span></span><span id="changeMonthHead" class="page headerMid col" style="display: none"><span id="backChangeYearPage"></span><span>年</span></span><span id="yearRight" class="right headerMid">>></span><span id="monthRight" class="right headerMid page">></span></div><div class="dateMain"><div id="firstPage" class="page firstPage" style="display: block"><div class="dateDay"><span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span></div><div id="dateBody" class="dateBody"></div></div><div id="secondPage" class="page secondPage" style="display: none"></div><div id="thirdPage" class="page secondPage" style="display: none" οnclick="chooseMonth()"><span><em id="month-1" index='1'>1月</em></span><span><em id="month-2" index='2'>2月</em></span><span><em id="month-3" index='3'>3月</em></span><span><em id="month-4" index='4'>4月</em></span><span><em id="month-5" index='5'>5月</em></span><span><em id="month-6" index='6'>6月</em></span><span><em id="month-7" index='7'>7月</em></span><span><em id="month-8" index='8'>8月</em></span><span><em id="month-9" index='9'>9月</em></span><span><em id="month-10" index='10'>10月</em></span><span><em id="month-11" index='11'>11月</em></span><span><em id="month-12" index='12'>12月</em></span></div></div></div> </body> <script src="js/index.js"></script> </html>

  

js部分:

// 默認(rèn)是當(dāng)天 var chosenDate = new Date(),year = chosenDate.getFullYear(),month = chosenDate.getMonth() + 1,date = chosenDate.getDate(),lastDateId = '', // 掛到全局下去lastYearId = '',lastMonthId = '',firstNum = 0;window.onload = function(){renderFirstPage(year, month, date);// input框獲取焦點(diǎn)時(shí)日歷顯示var datePicker = getIdDom('datePicker');getIdDom('textInput').onfocus = function(){datePicker.className = 'datePicker datePickerShow';}/* 以上是第一部分頁(yè)面展示 *//* 二級(jí)頁(yè)面 */var renderSecondPage = function(firstNum){var lastNum = firstNum + 9; // 二級(jí)頁(yè)面末尾數(shù)字getIdDom('changeYearFirst').innerHTML = firstNum;getIdDom('changeYearLast').innerHTML = lastNum;var yearTemplate = ``;for (var i = firstNum; i < lastNum + 1; i++) {if (i == year) {// 當(dāng)前選中年yearTemplate += `<span><em id="year-${i}" οnclick="chooseYear(this, ${i})" style="background-color: #39f;color: #fff">${i}</em></span>`} else {yearTemplate += `<span><em id="year-${i}" οnclick="chooseYear(this, ${i})">${i}</em></span>`}}getIdDom('secondPage').innerHTML = yearTemplate;}var reRenderSecondPage = function(){var yearStr = year.toString();var yearLastLetter = yearStr[yearStr.length-1]; // 末尾數(shù)firstNum = year - Number(yearLastLetter); // 二級(jí)頁(yè)面首位數(shù)字renderSecondPage(firstNum);}reRenderSecondPage();getIdDom("backChangeYearPage").innerHTML = year; // 三級(jí)頁(yè)面年份// click事件集中寫// 上一年下一年,上一月下一月的點(diǎn)擊事件clickFn('yearLeft', function(){if (getIdDom('changeYearHead').style.display != 'none') {// 此時(shí)是二級(jí)頁(yè)面,選年份if (firstNum - 10 < 1) {// 首位年份不能小于1return}firstNum -= 10;renderSecondPage(firstNum);} else {if (year - 1 < 1) {// 年份不能小于1return}year--;renderFirstPage(year, month, date);getIdDom("backChangeYearPage").innerHTML = year;reRenderSecondPage();}});clickFn('monthLeft', function(){if (month < 2) {// 1月month = 12;year--;} else {month--;}renderFirstPage(year, month, date)});clickFn('yearRight', function(){if (getIdDom('changeYearHead').style.display != 'none') {// 此時(shí)是二級(jí)頁(yè)面,選年份firstNum += 10;renderSecondPage(firstNum);} else {year++;renderFirstPage(year, month, date);getIdDom("backChangeYearPage").innerHTML = year;reRenderSecondPage();}});clickFn('monthRight', function(){if (month > 11) {// 12月month = 1;year++;} else {month++;}renderFirstPage(year, month, date)});clickFn('changeYear', function(){var pagesArr = Array.from(document.querySelectorAll('.page'));pagesArr.forEach(function(item){item.style = 'display: none'});reRenderSecondPage();changeStyle('secondPage', 'display: block');changeStyle('changeYearHead', 'display: inline-block');}); // 點(diǎn)擊年份切換至二級(jí)頁(yè)面clickFn('changeMonth', function(){var pagesArr = Array.from(document.querySelectorAll('.page'));pagesArr.forEach(function(item){item.style = 'display: none'});if (lastMonthId !== '') {// 非第一次點(diǎn)擊getIdDom(lastMonthId).style = "";}changeStyle("month-" + month, 'background-color: #39f;color: #fff');lastMonthId = 'month-' + month;changeStyle('thirdPage', 'display: block');changeStyle('changeMonthHead', 'display: inline-block');})clickFn('changeMonthHead', function(){// 切回年份選擇var pagesArr = Array.from(document.querySelectorAll('.page'));pagesArr.forEach(function(item){item.style = 'display: none'});changeStyle('secondPage', 'display: block');changeStyle('changeYearHead', 'display: inline-block');reRenderSecondPage();})document.getElementsByTagName('html')[0].onclick = function(e){// 這里模擬失去焦點(diǎn)事件var name = e.target.nodeName;if (name == 'BODY' || name == 'HTML') {datePicker.className = 'datePicker datePickerHide';}}}function getIdDom(id){return document.getElementById(id) } // 根據(jù)id獲取dom節(jié)點(diǎn)function clickFn(id, fn) {getIdDom(id).onclick = fn; } // 封裝一下click方法function renderFirstPage(year, month, date = 1){var datePage = []; // 最終展示頁(yè)面的所有日期合集 // 第一部分,上月月末幾天// 首先要知道上月一共多少天var getAlldays = (year, month) => {if (month <= 7) {// 1-7月if (month % 2 === 0) {// 偶數(shù)月if (month === 2) {// 2月特殊if ((year % 400 == 0) || ( year % 4 == 0 && year % 100 != 0)) {// 閏年var alldays = 29} else {var alldays = 28}} else {var alldays = 30}} else {// 奇數(shù)月var alldays = 31}} else {// 8-12月if (month % 2 === 0) {// 偶數(shù)月var alldays = 31} else {var alldays = 30}}return alldays}; // alldays表示某年某月的總天數(shù)var lastMonthAllDays = getAlldays(year, month - 1); // 上月天數(shù)var chosenFirstMonthDay = new Date(year, month - 1, 1).getDay(); // 當(dāng)月1號(hào)周幾var datePageTemplate = ``;var num = 0;for (var i = lastMonthAllDays - chosenFirstMonthDay + 1; i < lastMonthAllDays + 1; i++ ) {datePageTemplate += `<span id="lastMonth"><em id="last-${i}" οnclick="chooseDate(this, 'last-${i}', ${year}, ${month}, ${i})">${i}</em></span>`;num++;}// 第二部分,當(dāng)月總天數(shù)var chosenMonthAllDays = getAlldays(year, month); // 當(dāng)月天數(shù)var time = new Date();var a = time.getFullYear(),b = time.getMonth() + 1,c = time.getDate(); // 用來(lái)記錄當(dāng)天時(shí)間for(var i = 1; i < chosenMonthAllDays + 1; i++) {var chosenDateObj = {year: year,month: month,date: i};if (i === c && year === a && month === b) {// 今天日期高亮datePageTemplate += `<span id="today" class="currentMonth"><em id="today-${i}" οnclick="chooseDate(this, 'today-${i}', ${year}, ${month}, ${i})" class="today">${i}</em></span>`;} else {datePageTemplate += `<span id="currentMonth" class="currentMonth"><em id="cur-${i}" οnclick="chooseDate(this, 'cur-${i}', ${year}, ${month}, ${i})">${i}</em></span>`;}num++;}// 第三部分,剩余天數(shù)for (var i = 1; i < 43 - num; i++) {var chosenDateObj = {year: year,month: month,date: i};datePageTemplate += `<span id="nextMonth"><em id="nex-${i}" οnclick="chooseDate(this, 'nex-${i}', ${year}, ${month}, ${i})">${i}</em></span>`;}var templateString = `${datePageTemplate}`;var innerFn = function(id, content) {getIdDom(id).innerHTML = content};innerFn('dateYear', year);innerFn('dateMonth', month);innerFn('dateBody', templateString);}function chooseDate(item, index, year, month, date) {event.stopPropagation();if (lastDateId !== '') {// 非第一次點(diǎn)擊getIdDom(lastDateId).style = "";}// 選中項(xiàng)樣式改變,并且將input的日期修改lastDateId = index;item.style = "background-color: #39f;color: #fff";getIdDom("textInput").value = year + '-' + month + '-' + date; }function chooseYear(item, thisYear) {event.stopPropagation();if (lastYearId !== '') {// 非第一次點(diǎn)擊if (getIdDom(lastYearId)) {// 存在已經(jīng)跨頁(yè)面了,但是id不存在了getIdDom(lastYearId).style = "";}} else {// 第一次點(diǎn)擊getIdDom('year-' + year).style = "";}lastYearId = 'year-' + thisYear;year = thisYear;item.style = "background-color: #39f;color: #fff";var pagesArr = Array.from(document.querySelectorAll('.page'));pagesArr.forEach(function(item){item.style = 'display: none'});if (lastMonthId !== '') {// 非第一次點(diǎn)擊getIdDom(lastMonthId).style = "";}changeStyle("month-" + month, 'background-color: #39f;color: #fff');lastMonthId = 'month-' + month;getIdDom("backChangeYearPage").innerHTML = year;changeStyle('changeMonthHead', 'display: inline-block');changeStyle('thirdPage', 'display: block'); }function chooseMonth(){var target = event.target;if (target.nodeName === 'EM') {// 表示當(dāng)前點(diǎn)擊的為em節(jié)點(diǎn)if (lastMonthId !== '') {// 非第一次點(diǎn)擊getIdDom(lastMonthId).style = "";} else {// 第一次點(diǎn)擊getIdDom('month-' + month).style = "";}month = parseInt(target.innerHTML);lastMonthId = 'month-' + month;target.style = "background-color: #39f;color: #fff";renderFirstPage(year, month, date);// 展示首頁(yè)var pagesArr = Array.from(document.querySelectorAll('.page'));pagesArr.forEach(function(item){item.style = 'display: none'});changeStyle('firstPage', 'display: block');changeStyle(['changeDateHead', 'monthLeft', 'monthRight'], 'display: inline-block');} }// 判斷對(duì)象類型 function isType(type){return function(obj){return toString.call(obj) == '[object ' + type + ']';} }// 改變display屬性 function changeStyle(ids, styles){var isString = isType('String'),isArray = isType('Array');if (isString(ids)) {getIdDom(ids).style = styles;} else if (isArray(ids)) {ids.forEach(function(item){getIdDom(item).style = styles;})} }

  

  

css部分:

* {margin: 0;padding: 0; }*, :after, :before {box-sizing: border-box; }body {font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,\\5FAE\8F6F\96C5\9ED1,Arial,sans-serif; }.textInput {position: relative;display: block; }.datePicker {width: 216px;margin: 10px;color: #c3cbd6;border-radius: 4px;box-shadow: 0 1px 6px rgba(0,0,0,.2);transform-origin: center top 0px;transition: all .2s ease-in-out;position: absolute;left: 0px;top: 16px; } .datePickerHide {opacity: 0; }.datePickerShow {opacity: 1; }.dateHeader {height: 32px;line-height: 32px;text-align: center;border-bottom: 1px solid #e3e8ee; }.left, .right {display: inline-block;width: 20px;height: 24px;line-height: 26px;margin-top: 4px;text-align: center;cursor: pointer;color: #c3cbd6;-webkit-transition: color .2s ease-in-out;transition: color .2s ease-in-out; }.left {float: left;margin-left: 10px; }.right {float: right;margin-right: 10px; }.dateMain {margin: 10px; }.dateDay {line-height: normal;font-size: 0;letter-spacing:normal; }span {display: inline-block;text-align: center;font-size: 12px; }.dateDay span {line-height: 24px;width: 24px;height: 24px;margin: 2px; }.dateBody span {width: 28px;height: 28px;cursor: pointer; }.dateBody span em {display: inline-block;position: relative;width: 24px;height: 24px;line-height: 24px;margin: 2px;font-style: normal;border-radius: 3px;text-align: center;transition: all .2s ease-in-out; }.dateBody span.currentMonth {color: #657180; }.today:after {content: '';display: block;width: 6px;height: 6px;border-radius: 50%;background: #39f;position: absolute;top: 1px;right: 1px; }.currentMonth em:hover {background-color: #e1f0fe; }.col {color: #657180; }.headerMid {cursor: pointer; }.headerMid:hover {color: #39f; }/* second */ .secondPage {width: 196px;font-size: 0; }.secondPage span {display: inline-block;width: 40px;height: 28px;line-height: 28px;margin: 10px 12px;border-radius: 3px;cursor: pointer; }.secondPage span em {display: inline-block;width: 40px;height: 28px;line-height: 28px;margin: 0;font-style: normal;border-radius: 3px;text-align: center;transition: all .2s ease-in-out;color: #657180; }.secondPage span em:hover {background-color: #e1f0fe; }

  

GitHub項(xiàng)目地址:https://github.com/Yanchenyu/DatePicker

項(xiàng)目寫完了,但其實(shí)發(fā)現(xiàn)里面存在大量的DOM操作以及環(huán)境污染,這個(gè)對(duì)性能的損耗是相當(dāng)大的,寫得越多越發(fā)現(xiàn)狀態(tài)難以管理,都只能掛到全局下去,所以打算再寫一套R(shí)eact版本的。 end

?

轉(zhuǎn)載于:https://www.cnblogs.com/yanchenyu/p/8425141.html

總結(jié)

以上是生活随笔為你收集整理的JavaScript日历(es5版本)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。