利用原生JavaScript实现造日历*实例代码
前言
在日常开发中,大多数都是在和框架打交道,久而久之便遗忘了原生js的感觉,个人感觉中原生js基础还是很重要的,所以最近就利用了空余时间造一个*出来,虽然以我的水平造出来的*质量还是不太可靠的,但是我觉得用来练练手还是不错的,哈哈!!
so, let's begin!
github:github.com/zero-jian/p…
以下是日历的样子,是有点难看,讲究讲究,重点在于js部分,嘻嘻!!!
关于日历组件的实现思路
- 设置默认参数
- 检查节点参数是否传入,否则抛出错误
- 动态创建显示本日星期几的横轴
- 动态创建日历的日子
- 最后添加一点dom动作就好
先来看看构造函数内容
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('h1.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(); }
唔唔唔,整个日历组件下来大概就是这样子,整个流程写下来感觉自己的思维还是有所进步的,但是其实我觉得这个*代码还是可以再封装封装和完善的,嘻嘻~~
*功能比较简单,所以剩下的功能就等待小伙伴们*发挥了~~
好了,第一次写文章,熬夜写的,突然就有灵感了,不肯睡觉,呵呵,,明天上班肯定是要打瞌睡了,呵呵~~~
本人是小白,从业将近一年,所以代码上有什么错误,请各位大神能够指出指出,嗯嗯,完~~
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
下一篇: .NET简单工厂模式讲解
推荐阅读
-
利用原生JavaScript实现造日历*实例代码
-
基于javascript实现日历功能原理及代码实例
-
利用JavaScript实现新闻滚动效果(实例代码)_javascript技巧
-
使用原生javascript实现分页效果的代码实例
-
原生JavaScript实现动态省市县三级联动下拉框菜单实例代码_javascript技巧
-
基于javascript实现日历功能原理及代码实例
-
原生JavaScript实现动态省市县三级联动下拉框菜单实例代码_javascript技巧
-
如何利用JavaScript&jQuery实现滚动公告栏(代码实例)
-
如何利用JavaScript&jQuery实现滚动公告栏(代码实例)