美文网首页
日历选择

日历选择

作者: 云桃桃 | 来源:发表于2019-06-13 23:16 被阅读0次

    有一个问题一直困扰着我,效果是写出来了,但是如何优雅呢。。。

    2.gif
    • js
           var calender = {
            /**
             * 初始化
             */
            init: function (timeInterval) {
                var that = this;
                that.elmInit(timeInterval);
    
                that.currentMonthShow();
                that.bindEvent();
    
            },
            elmInit:function(timer){
                var that=this;
                that.yElem = document.getElementById('yearUnit');
                that.mElem = document.getElementById('monthUnit');
                that.calElem = document.getElementById('calender');
                that.inputElem = document.querySelector('.calender-wrapper .date-input');
                that.returnTodayBtn = document.querySelector('.calender-wrapper .return-btn');
                that.yearUnit(timer);
            },
            /**
             * 年份组件自定义
             */
            yearUnit:function(timer){
               var that=this,
                   yearOptStr='',years='';
               // 如果有时间间隔就显示年份区间的
               if(timer && timer.yearInterval){
                   years=timer.yearInterval.split('-');
                   for(var i=years[0];i<=years[1];i++){
                        yearOptStr+=`<option value="${i}">${i}年</option>`;
                   }
                   that.startYear=years[0];
                   that.endYear=years[1];
               //  如果没有年份区间 就选择当前年份之后五年的日期
               }else{
                   years=new Date().getFullYear();
                   for(var i=years;i<=years+5;i++){
                       yearOptStr+=`<option value="${i}">${i}年</option>`;
                   }
                   that.startYear=years;
                   that.endYear=years+5;
               }
                that.yElem.innerHTML=yearOptStr;
    
            },
            // 现在的日期
            nowDate: {},
            // 选择的日期
            chooseDate:{},
            /**
             * 现在当月的展示
             */
            currentMonthShow: function () {
                var that = this,
                    y = new Date().getFullYear(),
                    m = new Date().getMonth(),
                    d = new Date().getDate();
                   that.nowDate = that.dealDate(y, m, d);
                   that.changeShow(y,m,d);
            },
            /**
             * 日期处理
             * @param year
             * @param month
             * @param day
             * @returns {{d: string, month: *, y: *, m: string}}
             */
            dealDate: function (year, month, day) {
                var that = this, obj = {},
                    month = parseInt(month),
                    m = month >= 10 ? month : '0' + month,
                    d = day >= 10 ? day : '0' + day,
                    trueMonth = month + 1 >= 10 ? month + 1 : '0' + (month + 1);
                obj = {y: year, m: m, d: d, month: trueMonth};
                return obj;
            },
            /**
             * 顶部和日历都变化
             */
            changeShow: function (y,m,d,isCurMonth) {
                var that = this,
                    dates = that.dealDate(y,m,d);
                that.chooseDate=dates;
                that.topChooseShow(dates);
                // 这个当在当月选择的时候不需要更新日历显示
                if(!isCurMonth){
                    that.calenderShow(dates);
                }
            },
            /**
             * 顶部年月选择、日期时间展示
             * @param date
             */
            topChooseShow: function (date) {
                var that = this;
                that.yElem.value = date.y;
                that.mElem.value = parseInt(date.m);
                that.inputElem.value = `${date.y}-${date.month}-${date.d}`;
            },
            /**
             * 日历展示
             * @param date
             */
            calenderShow: function (date) {
                var that = this,
                    yearVal = parseInt(date.y),
                    monthVal = parseInt(date.m),
                    trueMonth = parseInt(date.month),
                    curMonthNum = new Date(yearVal, trueMonth, 0).getDate(),
                    beforeMonthNum = new Date(yearVal, trueMonth - 1, 0).getDate(),
                    weekDay = new Date(yearVal, monthVal, 1).getDay(),
                    str = '';
                // 处理前一个月的结束
                if (weekDay > 1) {
                    for (var i = beforeMonthNum - weekDay + 2; i <= beforeMonthNum; i++) {
                        str += `<li class="noexit before-month">${i}</li>`;
                    }
                } else if (weekDay <= 1) {
                    for (var i = beforeMonthNum - (6 + weekDay - 1); i <= beforeMonthNum; i++) {
                        str += `<li class="noexit before-month">${i}</li>`;
                    }
                }
                // 当月日历
                for (var k = 1; k <= curMonthNum; k++) {
                    // 如果是当月的 当天着重展示
                    if (yearVal == that.nowDate.y && monthVal == that.nowDate.m && that.nowDate.d == k) {
                        str += `<li class="today">${k}</li>`;
                    // 指定的天数 着重展示
                    } else if (date.d == k) {
                        str += `<li class="current">${k}</li>`;
                    } else {
                        str += `<li>${k}</li>`;
                    }
                }
                that.calElem.innerHTML = str;
                var liLen = document.querySelectorAll('#calender li').length;
                // 循环未来一个月的开始
                for (var n = 1; n <= 42 - liLen; n++) {
                    str += `<li class="noexit next-month">${n}</li>`;
                }
                that.calElem.innerHTML = str;
    
    
            },
            /**
             * 事件绑定
             */
            bindEvent: function () {
                var that = this;
                // 年份变更,回到选择年份第一月
                that.yElem.onchange = function (e) {
                    that.changeShow(this.value, 0, 1);
                }
                // 月份变更 显示选择的月份
                that.mElem.onchange = function (e) {
                    that.changeShow(that.yElem.value, this.value, 1);
                }
                // 回到当前
                that.returnTodayBtn.onclick = function () {
                    that.currentMonthShow();
                }
    
                // 日历点击
                that.calElem.addEventListener('click',function(e){
                    if(e.target.tagName.toLowerCase()=='li'){
                        var lis=this.querySelectorAll('li');
                        for(var m in lis){
                            lis[m].index=m;
                        }
                         var index=e.target.index,
                             day=e.target.innerHTML;
                        if (e.target.className.indexOf('before-month') > 0) {
                            if(that.chooseDate.y==that.startYear && that.chooseDate.m == 0){
                                console.log('不在范围内不能再选');
                                return;
                            }
                            if (that.chooseDate.m == 0) {
                                that.changeShow(that.chooseDate.y - 1, 11,day);
                            } else {
                                that.changeShow(that.chooseDate.y,that.chooseDate.m - 1,day);
                            }
                        }else if (e.target.className.indexOf('next-month') > 0) {
                            if(that.chooseDate.y==that.endYear && that.chooseDate.m == 11){
                                console.log('超出范围内不能再选');
                                return;
                            }
                            if (that.chooseDate.m == 11) {
                                that.changeShow(parseInt(that.chooseDate.y) + 1, 0,day);
                            } else {
                                that.changeShow(that.chooseDate.y, parseInt(that.chooseDate.m) + 1,day);
                            }
                        }else {
                            for (var nn = 0; nn < lis.length; nn++) {
                                if (lis[nn].className.indexOf('current') > -1) {
                                    lis[nn].classList.remove("current");
                                }
                            }
                            for (var mm = 0; mm < lis.length; mm++) {
                                if (lis[mm].index == index) {
                                    lis[mm].classList.add('current');
                                }
                            }
                            that.changeShow(that.chooseDate.y, that.chooseDate.m, day,true);
                        }
    
                    }
                    
                });
    
            }
    
        };
        // 可配置年份间隔
        calender.init({yearInterval:'2019-2021'});
        // calender.init();
    
    • **html **
    <div class="calender-wrapper">
    <div class="clear choose-box">
        <select class="drop-unit" name="" id="yearUnit">
            <option value="2011">2011年</option>
            <option value="2012">2012年</option>
            <option value="2013">2013年</option>
            <option value="2014">2014年</option>
            <option value="2015">2015年</option>
            <option value="2016">2016年</option>
            <option value="2017">2017年</option>
            <option value="2018">2018年</option>
            <option value="2019">2019年</option>
            <option value="2020">2020年</option>
        </select>
        <select class="drop-unit" name="" id="monthUnit">
            <option value="0">1月</option>
            <option  value="1">2月</option>
            <option  value="2">3月</option>
            <option value="3">4月</option>
            <option value="4">5月</option>
            <option value="5" >6月</option>
            <option value="6">7月</option>
            <option value="7">8月</option>
            <option  value="8">9月</option>
            <option value="9">10月</option>
            <option value="10">11月</option>
            <option value="11">12月</option>
        </select>
        <input class="date-input" type="text" readonly  value="">
        <span class="return-btn">回到当前</span>
    </div>
        <div>
    
        <ul class="canlender-box clear">
            <li>星期1</li>
            <li>星期2</li>
            <li>星期3</li>
            <li>星期4</li>
            <li>星期5</li>
            <li>星期6</li>
            <li>星期7</li>
        </ul>
    <ul id="calender" class="canlender-box clear">
     
    
    </ul>
    
        </div>
    
    </div>
    
    • css
    /*日历*/
    .calender-wrapper{width: 80%;
        margin: 20px auto;}
    .choose-box .drop-unit{ line-height: 30px; width: 20%; float: left;
        margin-right: 5%; height: 30px;}
    
    .calender-wrapper .date-input{float: left;
        line-height: 26px;padding: 0px 5px; margin-right: 10px}
    .calender-wrapper .return-btn{
        float: left;
        text-align: center;
        line-height: 30px;
        padding: 0px 10px;
        background-color: #0E9CFF;
        color: #fff;
        cursor: pointer;
    }
    .canlender-box li{
        border-bottom: 1px solid #333;
        font-size: 20px;
        float: left;
        width: 14%;  line-height: 50px;
        text-align: center;
        box-sizing: border-box;
        border-right: 1px solid #333;
        cursor: pointer;
    }
    .canlender-box{
        border-left:1px solid #333;
        margin: 20px 0px;
        width: 90%;
    }
    
    .canlender-box li.noexit{
        background-color: #ddd;
    }
    .canlender-box li.today{
        background-color: #0ff;
    }
    .canlender-box li.current{
        background-color: #f00;
    }
    
    .canlender-box li:nth-child(7n){
        border-right:1px solid #333;
    }
    /*选择前七个*/
    .canlender-box li:nth-child(-n+7){
        border-top:1px solid #333;
    }
    

    相关文章

      网友评论

          本文标题:日历选择

          本文链接:https://www.haomeiwen.com/subject/bpcyfctx.html