手撸日历控件

296 阅读2分钟

image.png

最近一直在看原生javascript和es6,太久没撸dom了,突然看了知乎上的一篇文章上的一个作者说“# 感觉自己学会了JavaScript所有基础知识,为什么老师留一个日历的作业我还是写不出来?”,当时我就有了一个念头,试试自己能不能手撸一个日历组件出来,于是就花了两天时间撸了一下,后面经过测试和优化终于出来了,目前是做到了主流浏览器兼容的如IE11是没问题的。但我选择PO出来的初衷是想让更多的比我优秀的亲们帮我指出其中的不足之处和性能更优的写法,不足之处请多多指教

下面附上核心代码:

//获取选择月份的天数

`getCurMonthDay: function(month) {
    var days;
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            days = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            days = 30;
            break;
        case 2:
            days = this.fnToggleYear(this.current.year) ? 29 : 28;
            break;
    }
    return days;
}`

获取当前月份一共有多少天

getDays: function(month) { // month = parseInt(month_2); this.current.month = month; this.days = this.getCurMonthDay(month); var html = '', total = 42; // 这个月从星期几开始 let { year, _month, day } = this.current; var start_week = new Date(year, month - 1, 1).getDay(); var prev_year = (month - 1) > 0 ? year : year - 1, prev_month = (month - 1) > 0 ? (month - 1) : 12, prev_month_days = this.getCurMonthDay(prev_month); var next_month_days = total - this.days - start_week, next_year = (month + 1) > 12 ? year + 1 : year, next_month = (month + 1) > 12 ? 1 : (month + 1); // 前面补充的日期 for (var i = start_week; i >= 0; i--) { let _day = this.formatDay(prev_month_days - i); let date = { prev_year, prev_month, _day }; html += '<li class="prev" ymd="' + (Object.values(date).join('-')) + '">' + _day + '</li>' } for (var i = 1; i <= this.days; i++) { let f_day = this.formatDay(i); let date = { year, month, f_day }; html += '<li class="' + (day == i ? 'select' : '') + '" ymd="' + (Object.values(date).join('-')) + '">' + f_day + '</li>' } // 后面补充的日期 for (var i = 1; i < next_month_days; i++) { let f_day = this.formatDay(i); let date = { next_year, next_month, f_day }; html += '<li class="next" ymd="' + (Object.values(date).join('-')) + '">' + f_day + '</li>' } this.setHtml('set-day' + this._el, html); this.fnChooseDay(); }

//选择日期

`fnChooseDay: function() {
    var vm = this;
    let lis = document.querySelectorAll('#set-day' + this._el + ' li');
    for (let item of lis) {
        item.onclick = function() {
            let cls = this.className;
            this.className = cls.indexOf('select') != -1 ? cls : cls + ' select';
            vm.current.day = this.innerText;
            if (cls.indexOf('prev') != -1 || cls.indexOf('next') != -1) {
                let date = this.getAttribute('ymd').split('-').map(item => parseInt(item));
                let [year, month, day] = date;
                vm.current = { year, month, day };
                vm.year_el.value = year;
                vm.getDays(month)
                vm.month_el.options[month - 1].selected = true;
            }
            for (let child of lis) {
                if (child != this) {
                    let c_cls = child.className;
                    if (c_cls.indexOf('select') != -1) {
                        child.className = c_cls.replace(/select/g, "");
                    }
                }
            }
        }
    }
}`

插件调用:new Calendar('test1', '2021-11-01');

源码地址:gitee.com/aliceeason/… 用git自行下载,不足之处请慷慨指出~