您好,登錄后才能下訂單哦!
前言
在日常開發中,大多數都是在和框架打交道,久而久之便遺忘了原生JS的感覺,個人感覺中原生JS基礎還是很重要的,所以最近就利用了空余時間造一個輪子出來,雖然以我的水平造出來的輪子質量還是不太可靠的,但是我覺得用來練練手還是不錯的,哈哈!!
So, Let's begin!
github:github.com/Zero-jian/p…
以下是日歷的樣子,是有點難看,講究講究,重點在于JS部分,嘻嘻!!!
關于日歷組件的實現思路
先來看看構造函數內容
constructor(options) { let defaluteOptions = { element: null, //這是節點 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: {}, } //賦值默認參數 this.options = Object.assign({}, defaluteOptions, options); //輪番就調用函數動態創建dom this.checkOptions()._generateTime()._generateWeekDay()._generateCurrentDay();
初始化創建Calendar類對象的時候設置數值,賦值默認參數以及調用方法來動態創建dom,相信小伙伴們看懂這段代碼沒壓力。
該輪子我全程都是用ES6寫的,畢竟程序員還是要跟上潮流的!!
賦值參數后開始輪番調用函數,首先調用的是**this.checkOptions()**方法,檢查節點是否存在
checkOptions() { //如果節點不存在直接拋出錯誤 if (!this.options.element) { throw new Error('element is request'); } return this; }
接下來就是獲取當天的年月日
畢竟是日歷,獲取當前的年月日當參考還是很重要的
_generateTime() { let data = new Date(); //時間 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; //日歷總日子數為7*6=42 this.options.days.noMonth = data.getMonth() + 1; //不變的月份 this.options.days.noYear = data.getFullYear(); //不變的年份 return this; }
創建星期橫軸
_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是封裝好的方法,傳入模板即可創建并返回回來
this.createArray()也是封裝好的方法,本函數是創建一個長度為7的數組,為什么長度為7?因為周一到周日的長度為7啊,然后開始使用map映射和遍歷來創建節點并添加document.body里面!!!
唔唔唔,去到這里,星期橫軸就創建好了,接下來是重點部分了,就是創建對于的星期的日子日歷,其實只要掌握邏輯就好了,不過因為我是菜雞,寫的時候也有點掉坑,所以,哈哈,你們對我寫的代碼參考參考就好了!!
接下來是重點了,就是創建日子
創建日歷日子分為三個部分,第一部分是上個月的日子,第二是本月的日子,第三部分是下個月的日子,三個部分所以把它們分別封裝起來,嫑相互影響!!
話不多說,貼上代碼
//創建當前月份日子 _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) //月份天數 let getMonthDay = this._getWeekDay(); //幾號 date.countDay = 0; date.countDay += getMonth; calendar.appendChild(ol); //創建當月日子模塊 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'); //判斷日歷起止,對本月日子進行賦值 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('h2.date').appendChild(dom.create(`<p data-role="time">${date.year}-${date.month}-${date.day}</p>`)); this._generatePrevMonth()._generateNextMonth(); }
創建當前月份日子的邏輯就是首先就是創建一個長度為42的數組,因為6*7=42,數組下標為0至42,然后獲取當月的天數以及當月一號時候是星期幾,通過計算獲取本月天數的下標范圍,然后通過循環進行賦值,這樣就創建了日歷本月的天數
然后是創建上個月的天數
按照慣例,貼上代碼
_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);//上月月份天數 let li = document.querySelectorAll('.dayLabel>.day'); beginWeek == 0 ? beginWeek+= 7 : ''; //如果月份開頭為星期日,會出bug,這是防止 date.countDay += beginWeek; this.createArray(beginWeek,this.options.startOfWeek).map((day,i)=>{ if(i<beginWeek) { //上月總天數-本月開始星期幾+1+i li[i].textContent = countMonth - beginWeek + 1 + i; } }); return this; }
創建上月的日子,首先獲取本月一號是星期幾,比如是星期三就可以知道前面空的數字分別為星期日、星期一和星期二,上月的天數能占三個位置,所以就創建一個長度為3的數組,然后計算上月的天數,然后通過邏輯判斷進行賦值,就是如此~~~
最后就是下一個月的天數
代碼 代碼 代碼
//創建下個月日子 _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);//下月月份天數 let li = document.querySelectorAll('.dayLabel>.day'); //data.countDay統計了上月和本月的日子數總量,直接減去即可 this.createArray(42-date.countDay , this.options.startOfWeek).map((day,i)=>{ li[date.countDay+i].textContent = i+1; }); }
這個邏輯比較簡單,就是用(6*7=42)42減去上月天數和本月天數,剩下的位置為顯示下個月的天數,所以就是這樣子!!!
把封裝好的代碼也弄出來吧~~
//dom.create()調用 let dom = { create(html) { let template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild; } }
//this.createArray()調用 //創建數組節點 createArray(length, fill) { let array = Array.apply(null, { length: length }).map(() => fill); return array; }
動作切換部分
切換日子這里相對來說就是比較簡單,我直接貼代碼,你們一看就懂了
//上一個月 previousMonth() { // this.options.days.month -= 1; this.changeMonth('prev'); } //下一個月 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; } } //移除節點 this._generateCalendar(); //重新添加節點 this._generateCurrentDay(); }
唔唔唔,整個日歷組件下來大概就是這樣子,整個流程寫下來感覺自己的思維還是有所進步的,但是其實我覺得這個輪子代碼還是可以再封裝封裝和完善的,嘻嘻~~
輪子功能比較簡單,所以剩下的功能就等待小伙伴們自由發揮了~~
好了,第一次寫文章,熬夜寫的,突然就有靈感了,不肯睡覺,呵呵,,明天上班肯定是要打瞌睡了,呵呵~~~
本人是小白,從業將近一年,所以代碼上有什么錯誤,請各位大神能夠指出指出,嗯嗯,完~~
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。