使用原生js实现一个简单的datePicker组件

javascript.png

这篇文章是我看了慕课网的datePicker组件开发课程写的,其中加了一些自己的思考和总结,具体源码大家可以参考慕课网相关代码

1,实现的效果

datepacker.gif

2,基础知识点

JavaScript Date(日期)对象 实例

  • 返回当日的日期和时间

    var today = new Date();
    
  • 从 Date 对象返回一个月中的某一天 (1 ~ 31)

    today.getDate()
    
  • 从 Date 对象返回一周中的某一天 (0 ~ 6);注意:星期天是0

    today.getDay()
    
  • 从 Date 对象以四位数字返回年份

    today.getFullYear()
    
  • 从 Date 对象返回月份 (0 ~ 11)

    today.getMonth()
    
  • 返回 Date 对象的小时 (0 ~ 23)

    today.getHours()
    
  • 返回 Date 对象的分钟 (0 ~ 59)。

    today.getMinutes()
    
  • 返回 1970 年 1 月 1 日至今的毫秒数。

    today.getTime()
    
  • 返回某一个日期的Date对象

    // 比如我要拿到5月27号的Date对象
    
    var aDay = new Date('2018-05-27')
    或者
    var aDay = new Date(2018,4,27) // 月份是从0开始的
    

更多可以参考JavaScript Date 对象;

3,页面结构

这里我们就不细讲了,我们会在第五节讲动态渲染日历数据。

4,获取日历每月显示的数据

首先我们要实现一个函数,这个函数的作用就是拿到我们这个 datePicker 需要渲染的数据。

我们实现的六行七列的数据,如下图:

demo4.png

我们首先创建一个 data.js ,同时在里面定义一个 getMonthDate 的方法,在 ret 存入我们所要渲染的天数。

(function(){
    var datepicker = {};
    
    datepicker.getMonthDate = function(year ,month){
        
        var ret = [];

        return {
            days:ret
        };

    }
    
    window.datepicker = datepicker;
})();

这个函数需要接受的参数是年份与月份,如果不传的话,则默认传入当前的月份与年份。

如下:

if(!year&&!month){
    var today =  new  Date(); // 获取当天日期对象
    year = today.getFullYear(); // 获取当前年份
    month = today.getMonth() + 1; // 获取当前月份
}

这里面还有一个比较重要的点就是,就是我们怎么显示上一个月的值,以及他们分别是几号。

demo3.png

这里我们只要获取到这个月第一天是星期几就可以了,然后前面的就是相应显示上个月的值。

var firstDay = new Date(year ,month-1, 1); // 这个月第一天的Date对象
var firstDayWeekDay = firstDay.getDay(); // 那个这个月第一天具体是星期几

if(firstDayWeekDay === 0)firstDayWeekDay = 7; // 0的话就是星期天

year = firstDay.getFullYear(); // 拿到当前的年份
month = firstDay.getMonth() + 1; // 拿到当前的月份

我们还需要拿到上个月和这个月的最后一天,便于我们稍后组装数据。我们可以用这个月的第0天得到上个月的最后一天。

var lastDayofLastMonth = new Date(year,month-1,0); // 上个月的最后一天
var lastDateofLastMonth = lastDayofLastMonth.getDate(); 
// 上个月的具体日期
var preMonthDayCount = firstDayWeekDay-1;  // 上个月在第一行要显示几天

var lastDay = new Date(year,month,0); // 这个月的最后一天
var lastData = lastDay.getDate();   // 这个月的最后一天具体日期 

接下去我们就需要去拼装数据了。

遍历数据:

数据结构的图我刚刚已经发过了,我们这边需要循环遍历这六行七列的42个数据,而且每一个数据包括

{
    date : 代表我们时当月的第几天,其实是一个中介,为了计算showDate
    month : 代表我们是第几个月
    showDate : 代表我们当前天数是确切的第几天
}

遍历的代码如下:

for (var i = 0;i<6*7;i++){
    var date = i+1-preMonthDayCount; // 赋值date的值,这里上个月的最后一天为0
    var showDate = date; // 赋值showDate,上下月份,下面再做判断
    var thisMonth = month; // 赋值月份
            
    if (date <= 0){             // 当date < 0时,则代表是上一个月
        thisMonth = month-1;    // 月份减一
        showDate = lastDateofLastMonth + date;  // 显示上一个相应是几号
    } else if (date > lastData){  // 当date大于了这个月最后一天,那么代表下个月
        thisMonth = month+1;    // 月份加一
        showDate = showDate - lastData;         // 显示下一个月具体几号
    }
                    
    if(thisMonth === 13) thisMonth = 1; 
    // 当我们月份是13的时候,代表下一年,月份置为一
    if(thisMonth === 0)thisMonth = 12;
    // 当我们月份是0的时候,代表上一年,月份置为一
    ret.push({
        date:date,
        month:thisMonth,
        showDate:showDate
    });                 // 最后塞入到我们的ret中去
}

经过以上代码的处理,我们便能得到最初图中所示的数据了。

5,开始动态渲染数据

我们在建一个 datePicker.js ,我们在这个 js 中做一些页面渲染的工作。

首先我们要来思考一下我们要做一些什么工作,一般在下手开始敲代码之前,我们先要想好思路,然后在开始工作。

demo.png

最开始,我们肯定要获取到日历数据,然后将数据动态填充到我们准备好的模版里面去。

然后我们要实现一些事件,改变月份,然后进行相应的的月份数据;点击相应的天数,使日历组件消失,input框中显示选择的天数。

这样我们可以写一个代码的大致框架出来:

(function(){
    var datepicker = window.datepicker;

    datepicker.buildUI = function(year ,month){ // 日历组件的函数
        var html = datepicker.buildUI(year,month);
        return html;
    };
    
    datepicker.render = function(direction){ // 页面的render函数
        var year,month;
        
        var html = datepicker.buildUI(year,month);
        
        $wrapper = document.querySelector('.ui-datePicker-wrapper');

        $wrapper.innerHTML = html;
        
    }
    
    datepicker.init = function(input){ // 页面的入口函数
        datepicker.render();        
    }
    
    function format(date){ // 一个工具函数,将Date对象转化成YYYY-MM-DD的格式
        var ret = '';
        var padding =  function(num){
            if(num <= 9){
                return  '0' + num;
            }else{
                return num;
            }
        }
        ret += date.getFullYear() + '-';
        ret += padding(date.getMonth() + 1) + '-';
        ret += padding(date.getDate()); 
        
        return  ret;
    }

})();

然后我们在 init 函数中添加一些事件函数,如下图:

demo4.png

接下来我们主要看看 buildUI 的函数实现,这里其实就是实现一个动态的html,然后渲染到页面中而已,就跟我们平时从 Ajax 渲染数据一样。

demo5.png

最后我们看看index.html的文件内容怎么样,如下图:

index.png

页面引入两个js,并向外暴露一个变量对象 datepicker ,然后调用相应的 init 方法。

6,总结

至此我们便完成了一个简单的用原生js完成的一个最最基础的日历组件,其中里面最主要的就是获取日期数据的这个函数,实现的思路其实也很常规,其他的关于渲染的流程,其实我们平时工作中也会经常碰到。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容