js实现日历组件

经历千辛万苦终于成功做好了一个日历组件了(泪目
直接创建文件,复制粘贴就可以在网页上实现了

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>日期选择器</title>
    <link rel="stylesheet" href="style.css">
    <style>
        .datepicker {
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 230px;
            padding: 5px;
            line-height: 24px;
        }
        .datepicker:focus {
            outline: none;
            border: 1px solid #1abc9c;
        }
    </style>
</head>
<body>
    <input type="text" class="datepicker">   
</body>
<script src="./data.js"></script>
<script src="./main.js"></script>
<script>
    // var monthDate = datepicker.getMonthDate(2019, 2);
    // console.log(monthDate);
    // datepicker.init(document.querySelector('.ui-datepicker-wrapper'))
    datepicker.init('.datepicker');
</script>
</html>

data.js

(function(){
    var datepicker = {};
    datepicker.getMonthDate = function (year, month) {
        var ret = [];
        if(!year || !month){
            var today = new Date();
            year = today.getFullYear();
            month = today.getMonth() + 1;
        }
        var firstDay = new Date(year, month-1, 1);//获取当月第一天
        var firstDayWeekDay = firstDay.getDay();//获取星期几,才好判断排在第几列
        if(firstDayWeekDay === 0){//周日
            firstDayWeekDay = 7;
        }

        year = firstDay.getFullYear();
        month = firstDay.getMonth() + 1;

        var lastDayOfLastMonth = new Date(year, month-1, 0);//获取最后一天
        var lastDateOfLastMonth = lastDayOfLastMonth.getDate();

        var preMonthDayCount = firstDayWeekDay - 1;
        var lastDay = new Date(year, month, 0);
        var lastDate = lastDay.getDate();

        for(var i=0; i<7*6; i++){
            var date = i + 1 - preMonthDayCount;
            var showDate = date;
            var thisMonth = month;
            //上一月
            if(date <= 0){
                thisMonth = month - 1;
                showDate = lastDateOfLastMonth + date;
            }else if(date > lastDate){
                //下一月
                thisMonth = month + 1;
                showDate = showDate -lastDate;
            } 
            if(thisMonth === 0){
                thisMonth = 12;
            }
            if(thisMonth === 13){
                thisMonth = 1;
            }
            ret.push({
                month: thisMonth,
                date: date,
                showDate: showDate
            })
            
        }
        return {
            year: year,
            month:month,
            days: ret
        };
    }
    window.datepicker = datepicker;//该函数唯一暴露的对象
})();

main.js

(function () {

    var datepicker = window.datepicker;

    var monthData;
    var $wrapper;
    //渲染函数,由于没有使用第三方插件或库,所以使用的是模板拼接的方法
    datepicker.buildUi = function (year, month) {
        monthData = datepicker.getMonthDate(year, month);
        var html = '<div class="ui-datepicker-header">' +
                        '<a href="#" class="ui-datepicker-btn ui-datepicker-prev-btn">&lt;</a>' +
                        '<a href="#" class="ui-datepicker-btn ui-datepicker-next-btn">&gt;</a>' +
                        '<span class="datepicker-curr-month">'+monthData.year+'-'+monthData.month+'</span>' +
                   '</div>' +
                   '<div class="ui-datepicker-body">' +
                        '<table>' +
                            '<thead>' +
                                '<tr>' +
                                    '<th>一</th>' +
                                    '<th>二</th>' +
                                    '<th>三</th>' +
                                    '<th>四</th>' +
                                    '<th>五</th>' +
                                    '<th>六</th>' +
                                    '<th>日</th>' +
                                '</tr>' +
                            '</thead>' +
                            '<tbody>';

                                for (var i = 0; i < monthData.days.length; i++) {
                                    var date = monthData.days[i];
                                    if (i % 7 === 0) {
                                        html += '<tr>';
                                    }
                                    html += '<td data-date="'+date.date+'">' + date.showDate + '</td>';
                                    if (i % 7 === 6) {
                                        html += '</tr>';
                                    }
                                }

                            html+='</tbody>' +
                        '</table>'+
                    '</div>';
        return html;
    };
    //日历渲染函数
    datepicker.render = function (direction) {
        var year, month;
        if (monthData) {
            year = monthData.year;
            month = monthData.month;
        }

        if (direction === 'prev') month--;
        if (direction === 'next') month++;

        var html = datepicker.buildUi(year,month);

        $wrapper=document.querySelector('.ui-datepicker-wrapper');

        if(!$wrapper){
            $wrapper = document.createElement('div');
            $wrapper.className = 'ui-datepicker-wrapper';
        }

        $wrapper.innerHTML = html;

        document.body.appendChild($wrapper);

    };
    //初始换函数
    datepicker.init = function (input) {
        datepicker.render();

        var $input=document.querySelector(input);
        var isOpen=false;
        //给input框赋予点击事件
        $input.addEventListener('click',function(){
            if(isOpen){
                $wrapper.classList.remove('ui-datepicker-wrapper-show');
                isOpen=false;
            }else{
                $wrapper.classList.add('ui-datepicker-wrapper-show');

                var left=$input.offsetLeft;
                var top=$input.offsetTop;
                var height=$input.offsetHeight;

                $wrapper.style.top=top+height+2+'px';
                $wrapper.style.left=left+'px';

                isOpen=true;
            }
        },false);
        //给按钮添加点击事件
        $wrapper.addEventListener('click',function(e){
            var $target=e.target;

            if(!$target.classList.contains('ui-datepicker-btn')){
                return false;
            }

            //上一月,下一月
            if($target.classList.contains('ui-datepicker-prev-btn')){
                datepicker.render('prev');
            }else if($target.classList.contains('ui-datepicker-next-btn')){
                datepicker.render('next');
            }
        },false);

        $wrapper.addEventListener('click',function(e){
            var $target= e.target;

            if($target.tagName.toLocaleLowerCase()!=='td'){
                return false;
            }

            var date=new Date(monthData.year,monthData.month-1,$target.dataset.date);

            $input.value=format(date);

            $wrapper.classList.remove('ui-datepicker-wrapper-show');
            isOpen=false;

        },false);
    };
    //格式化数据
    function format(date){
        var ret='';

        var padding=function(num){
            if(num<=9){
                return '0'+num;
            }
            return num;
        };

        ret+=date.getFullYear()+'-';
        ret+=padding(date.getMonth()+1)+'-';
        ret+=padding(date.getDate());

        return ret;
    }

})();

style.css

/* 最外层区域 */
.ui-datepicker-wrapper {
    width: 240px;
    font-size: 16px;
    color: #666666;
    box-shadow: 2px 2px 8px 2px rgba(128, 128, 128, 0.3);
    display: none;
    position: absolute;
}
.ui-datepicker-wrapper-show {
    display: block;
}

/* 头部区域 */
.ui-datepicker-wrapper .ui-datepicker-header {
    padding: 0 20px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    background: #f0f0f0;
    border-bottom: 1px solid #cccccc;
    font-weight: bold;
}
/* 设置两个按钮 */
.ui-datepicker-wrapper .ui-datepicker-btn {
    font-family: serif;
    font-size: 20px;
    width: 20px;
    height: 50px;
    line-height: 50px;
    color: #1abc9c;
    text-align: center;
    cursor: pointer;
    text-decoration: none;
}
.ui-datepicker-wrapper .ui-datepicker-prev-btn {
    float: left;
}
.ui-datepicker-wrapper .ui-datepicker-next-btn {
    float: right;
}
/* body区域 */
.ui-datepicker-wrapper .ui-datepicker-body table {
    width: 100%;
    border-collapse: collapse;
}
/* 表头和正文 */
.ui-datepicker-wrapper .ui-datepicker-body th,
.ui-datepicker-wrapper .ui-datepicker-body td {
    height: 30px;
    text-align: center;
}
.ui-datepicker-wrapper .ui-datepicker-body th {
    font-size: 12px;
    height: 40px;
    line-height: 40px;
}
/* 表格部分 */
.ui-datepicker-wrapper .ui-datepicker-body td {
    border: 1px solid #f0f0f0;
    font-size: 10px;
    width: 14%;
    cursor: pointer;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值