最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

利用原生JavaScript實(shí)現(xiàn)造日歷輪子實(shí)例代碼

來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:57:29
文檔

利用原生JavaScript實(shí)現(xiàn)造日歷輪子實(shí)例代碼

利用原生JavaScript實(shí)現(xiàn)造日歷輪子實(shí)例代碼:前言 在日常開發(fā)中,大多數(shù)都是在和框架打交道,久而久之便遺忘了原生JS的感覺,個(gè)人感覺中原生JS基礎(chǔ)還是很重要的,所以最近就利用了空余時(shí)間造一個(gè)輪子出來,雖然以我的水平造出來的輪子質(zhì)量還是不太可靠的,但是我覺得用來練練手還是不錯(cuò)的,哈哈。
推薦度:
導(dǎo)讀利用原生JavaScript實(shí)現(xiàn)造日歷輪子實(shí)例代碼:前言 在日常開發(fā)中,大多數(shù)都是在和框架打交道,久而久之便遺忘了原生JS的感覺,個(gè)人感覺中原生JS基礎(chǔ)還是很重要的,所以最近就利用了空余時(shí)間造一個(gè)輪子出來,雖然以我的水平造出來的輪子質(zhì)量還是不太可靠的,但是我覺得用來練練手還是不錯(cuò)的,哈哈。

前言

在日常開發(fā)中,大多數(shù)都是在和框架打交道,久而久之便遺忘了原生JS的感覺,個(gè)人感覺中原生JS基礎(chǔ)還是很重要的,所以最近就利用了空余時(shí)間造一個(gè)輪子出來,雖然以我的水平造出來的輪子質(zhì)量還是不太可靠的,但是我覺得用來練練手還是不錯(cuò)的,哈哈??!

So, Let's begin!

github:github.com/Zero-jian/p…

以下是日歷的樣子,是有點(diǎn)難看,講究講究,重點(diǎn)在于JS部分,嘻嘻!??!

關(guān)于日歷組件的實(shí)現(xiàn)思路

  • 設(shè)置默認(rèn)參數(shù)
  • 檢查節(jié)點(diǎn)參數(shù)是否傳入,否則拋出錯(cuò)誤
  • 動(dòng)態(tài)創(chuàng)建顯示本日星期幾的橫軸
  • 動(dòng)態(tài)創(chuàng)建日歷的日子
  • 最后添加一點(diǎn)dom動(dòng)作就好
  • 先來看看構(gòu)造函數(shù)內(nèi)容

    constructor(options) {
     let defaluteOptions = {
     element: null, //這是節(jié)點(diǎn)
     startOfWeek: 1,
     strings: {
     week: n => {
     let map = {
     0: '周日',
     1: '周一',
     2: '周二',
     3: '周三',
     4: '周四',
     5: '周五',
     6: '周六',
     }
     return map[n];
     },
     templateDay: `<li class="currentMonth">
     <span class="dayLabel">
     <span class="day"></span>
     <span class="unit">日</span>
     </span>
     </li>`
     },
     days: {},
     }
     //賦值默認(rèn)參數(shù)
     this.options = Object.assign({}, defaluteOptions, options);
     //輪番就調(diào)用函數(shù)動(dòng)態(tài)創(chuàng)建dom
     this.checkOptions()._generateTime()._generateWeekDay()._generateCurrentDay();

    初始化創(chuàng)建Calendar類對(duì)象的時(shí)候設(shè)置數(shù)值,賦值默認(rèn)參數(shù)以及調(diào)用方法來動(dòng)態(tài)創(chuàng)建dom,相信小伙伴們看懂這段代碼沒壓力。

    該輪子我全程都是用ES6寫的,畢竟程序員還是要跟上潮流的!!

    賦值參數(shù)后開始輪番調(diào)用函數(shù),首先調(diào)用的是**this.checkOptions()**方法,檢查節(jié)點(diǎn)是否存在

    checkOptions() {
     //如果節(jié)點(diǎn)不存在直接拋出錯(cuò)誤
     if (!this.options.element) {
     throw new Error('element is request');
     }
     return this;
     }

    接下來就是獲取當(dāng)天的年月日

    畢竟是日歷,獲取當(dāng)前的年月日當(dāng)參考還是很重要的

    _generateTime() {
     let data = new Date(); //時(shí)間
     let year = this.options.days.year = data.getFullYear(); //年份
     let month = this.options.days.month = data.getMonth() + 1; //月份
     let day = this.options.days.day = data.getDate(); //日子
     this.options.days.countDay = 0; //日歷總?cè)兆訑?shù)為7*6=42
     this.options.days.noMonth = data.getMonth() + 1; //不變的月份
     this.options.days.noYear = data.getFullYear(); //不變的年份
     return this;
     }

    創(chuàng)建星期橫軸

     _generateWeekDay() {
     let {
     startOfWeek,
     strings
     } = this.options;
     let calendar = document.querySelector('.calendar');
     let ol = dom.create(`<ol class="weekdays"></ol>`);
     calendar.appendChild(ol);
     let weekIndex = this.createArray(7, startOfWeek).map((day, i) => {
     let li = dom.create(`<li>${strings.week(i)}</li>`);
     //判斷是否為今天
     ol.appendChild(li);
     });
     return this;
     }

    dom.create是封裝好的方法,傳入模板即可創(chuàng)建并返回回來

    this.createArray()也是封裝好的方法,本函數(shù)是創(chuàng)建一個(gè)長(zhǎng)度為7的數(shù)組,為什么長(zhǎng)度為7?因?yàn)橹芤坏街苋盏拈L(zhǎng)度為7啊,然后開始使用map映射和遍歷來創(chuàng)建節(jié)點(diǎn)并添加document.body里面?。?!

    唔唔唔,去到這里,星期橫軸就創(chuàng)建好了,接下來是重點(diǎn)部分了,就是創(chuàng)建對(duì)于的星期的日子日歷,其實(shí)只要掌握邏輯就好了,不過因?yàn)槲沂遣穗u,寫的時(shí)候也有點(diǎn)掉坑,所以,哈哈,你們對(duì)我寫的代碼參考參考就好了?。?br />

    接下來是重點(diǎn)了,就是創(chuàng)建日子

    創(chuàng)建日歷日子分為三個(gè)部分,第一部分是上個(gè)月的日子,第二是本月的日子,第三部分是下個(gè)月的日子,三個(gè)部分所以把它們分別封裝起來,嫑相互影響??!

    話不多說,貼上代碼

     //創(chuàng)建當(dāng)前月份日子
     _generateCurrentDay() {
     let date = this.options.days;
     let calendar = document.querySelector('.calendar');
     let ol = dom.create(`<ol class="days"></ol>`);
     let getWeek = this._getWeekWeek(date.year, date.month-1, date.day); //星期幾
     let getMonth = this._getMonth(date.year, date.month) //月份天數(shù)
     let getMonthDay = this._getWeekDay(); //幾號(hào)
     date.countDay = 0;
     date.countDay += getMonth;
     calendar.appendChild(ol);
     //創(chuàng)建當(dāng)月日子模塊
     let dayIndex = this.createArray(42, this.options.startOfWeek).map((day, i) => {
     let li = dom.create(this.options.strings.templateDay);
     let span = li.querySelector('.dayLabel>.day');
     //判斷日歷起止,對(duì)本月日子進(jìn)行賦值
     if (i >= getWeek && i <= (getMonth + getWeek)) {
     span.textContent = i - getWeek;
     }
    
     //判斷是否為今天
     if (i == (getMonthDay + getWeek) && date.noMonth == date.month && date.noYear == date.year) {
     li.classList.add('today');
     }
     ol.appendChild(li);
     });
     document.querySelector('h1.date').appendChild(dom.create(`<p data-role="time">${date.year}-${date.month}-${date.day}</p>`));
     this._generatePrevMonth()._generateNextMonth();
    
     }

    創(chuàng)建當(dāng)前月份日子的邏輯就是首先就是創(chuàng)建一個(gè)長(zhǎng)度為42的數(shù)組,因?yàn)?*7=42,數(shù)組下標(biāo)為0至42,然后獲取當(dāng)月的天數(shù)以及當(dāng)月一號(hào)時(shí)候是星期幾,通過計(jì)算獲取本月天數(shù)的下標(biāo)范圍,然后通過循環(huán)進(jìn)行賦值,這樣就創(chuàng)建了日歷本月的天數(shù)

    然后是創(chuàng)建上個(gè)月的天數(shù)

    按照慣例,貼上代碼

    _generatePrevMonth() {
     let date = this.options.days;
     let year = date.year;
     let month = date.month;
     let beginWeek = this._getWeekWeek(year,month-1,1);//本月開始星期
     let countMonth = this._getMonth(year,month-1);//上月月份天數(shù)
     let li = document.querySelectorAll('.dayLabel>.day');
     beginWeek == 0 ? beginWeek+= 7 : ''; //如果月份開頭為星期日,會(huì)出bug,這是防止
     date.countDay += beginWeek;
     this.createArray(beginWeek,this.options.startOfWeek).map((day,i)=>{
     if(i<beginWeek) {
     //上月總天數(shù)-本月開始星期幾+1+i
     li[i].textContent = countMonth - beginWeek + 1 + i;
     }
     }); 
     return this;
     }

    創(chuàng)建上月的日子,首先獲取本月一號(hào)是星期幾,比如是星期三就可以知道前面空的數(shù)字分別為星期日、星期一和星期二,上月的天數(shù)能占三個(gè)位置,所以就創(chuàng)建一個(gè)長(zhǎng)度為3的數(shù)組,然后計(jì)算上月的天數(shù),然后通過邏輯判斷進(jìn)行賦值,就是如此~~~

    最后就是下一個(gè)月的天數(shù)

    代碼 代碼 代碼

    //創(chuàng)建下個(gè)月日子
    _generateNextMonth() {
     let date = this.options.days;
     let year = date.year;
     let month = date.month;
     let beginWeek = this._getWeekWeek(year,month,1);//開始星期
     let countMonth = this._getMonth(year,month+1);//下月月份天數(shù)
     let li = document.querySelectorAll('.dayLabel>.day');
     //data.countDay統(tǒng)計(jì)了上月和本月的日子數(shù)總量,直接減去即可
     this.createArray(42-date.countDay , this.options.startOfWeek).map((day,i)=>{
     li[date.countDay+i].textContent = i+1;
     });
     }

    這個(gè)邏輯比較簡(jiǎn)單,就是用(6*7=42)42減去上月天數(shù)和本月天數(shù),剩下的位置為顯示下個(gè)月的天數(shù),所以就是這樣子?。?!

    把封裝好的代碼也弄出來吧~~

    //dom.create()調(diào)用
    let dom = {
     create(html) {
     let template = document.createElement('template');
     template.innerHTML = html;
     return template.content.firstChild;
     }
    }
     //this.createArray()調(diào)用
     //創(chuàng)建數(shù)組節(jié)點(diǎn)
     createArray(length, fill) {
     let array = Array.apply(null, {
     length: length
     }).map(() => fill);
     return array;
     }

    動(dòng)作切換部分

    切換日子這里相對(duì)來說就是比較簡(jiǎn)單,我直接貼代碼,你們一看就懂了

     //上一個(gè)月
     previousMonth() {
     // this.options.days.month -= 1;
     this.changeMonth('prev');
     }
    
     //下一個(gè)月
     nextMonth() {
     // this.options.days.month += 1;
     this.changeMonth('next');
     }
    
     //回到今天
     resetMonth() {
     // this._generateTime();
     this.changeMonth('defalut');
     }
    
     //封裝月份dom
     changeMonth(status) {
     let date = this.options.days;
     switch(status) {
     case 'prev': {
     --date.month < 1 ? date.year-- ? date.month = 12 : '' : '';
     break;
     }
    
     case 'next': {
     ++date.month > 12 ? date.year++ ? date.month = 1 : '' : '';
     break;
     }
    
     case 'defalut': {
     this._generateTime();
     break;
     }
     }
     //移除節(jié)點(diǎn)
     this._generateCalendar();
     //重新添加節(jié)點(diǎn)
     this._generateCurrentDay();
     }

    唔唔唔,整個(gè)日歷組件下來大概就是這樣子,整個(gè)流程寫下來感覺自己的思維還是有所進(jìn)步的,但是其實(shí)我覺得這個(gè)輪子代碼還是可以再封裝封裝和完善的,嘻嘻~~

    輪子功能比較簡(jiǎn)單,所以剩下的功能就等待小伙伴們自由發(fā)揮了~~

    好了,第一次寫文章,熬夜寫的,突然就有靈感了,不肯睡覺,呵呵,,明天上班肯定是要打瞌睡了,呵呵~~~

    本人是小白,從業(yè)將近一年,所以代碼上有什么錯(cuò)誤,請(qǐng)各位大神能夠指出指出,嗯嗯,完~~

    總結(jié)

    聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    利用原生JavaScript實(shí)現(xiàn)造日歷輪子實(shí)例代碼

    利用原生JavaScript實(shí)現(xiàn)造日歷輪子實(shí)例代碼:前言 在日常開發(fā)中,大多數(shù)都是在和框架打交道,久而久之便遺忘了原生JS的感覺,個(gè)人感覺中原生JS基礎(chǔ)還是很重要的,所以最近就利用了空余時(shí)間造一個(gè)輪子出來,雖然以我的水平造出來的輪子質(zhì)量還是不太可靠的,但是我覺得用來練練手還是不錯(cuò)的,哈哈。
    推薦度:
    標(biāo)簽: 利用 輪子 calendar
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top