js写日历插件

52 篇文章 1 订阅
38 篇文章 0 订阅

慕课网课程网址:DatePicker组件开发

<!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>
    <style>
        .calendar {
            width: 240px;
            /* font-size: 16px; */
            color: #666;
            box-shadow: 2px 2px 8px 2px rgba(128, 128, 128, 0.3);
            display: none;
            position: absolute;
        }
        
        .calendar-show {
            display: block;
        }
        
        .calendar .calendar-header {
            padding: 0 20px;
            height: 40px;
            line-height: 40px;
            background: #eee;
            text-align: center;
            font-weight: bold;
        }
        
        .calendar .btn {
            text-decoration: none;
            font-size: 20px;
            color: indianred;
            width: 20px;
            height: 40px;
            line-height: 40px;
        }
        
        .calendar .btn-prev {
            float: left;
        }
        
        .calendar .btn-next {
            float: right;
        }
        
        .calendar .calendar-body table {
            width: 100%;
            border-collapse: collapse;
            text-align: center;
        }
        
        .calendar .calendar-body table thead {
            height: 40px;
            line-height: 40px;
            font-size: 14px;
        }
        
        .calendar .calendar-body table td {
            height: 30px;
            border: 1px solid #f0f0f0;
            font-size: 12px;
            cursor: pointer;
        }
        
        #datepicker {
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 240px;
            height: 24px;
            line-height: 24px;
        }
        
        #datepicker:focus {
            outline: 0 none;
            border: 1px solid #1abc9c;
        }
    </style>
</head>

<body>
    <input type="text" id="datepicker">

    <script>
        (function() {
            var datepicker = {};
            // 获取一个月的每一天数据
            datepicker.getMonthData = 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();

                // 一个月可能有4-6周,按6周计算
                for (var i = 0; i < 7 * 6; i++) {
                    // date记录当月当天的月日期
                    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
                };
            };

            var monthData;
            var divDom;
            datepicker.buildUi = function(year, month) {
                monthData = datepicker.getMonthData(year, month);
                var html = '<div class="calendar-header">' +
                    '<a href="#" class="btn btn-prev">&lt;</a>' +
                    '<span>' + monthData.year + '-' + monthData.month + '</span>' +
                    '<a href="#" class="btn btn-next">&gt;</a>' +
                    '</div>' +
                    '<div class="calendar-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++;

                // 创建日历,这里要判断如果日历已经存在的话就不用创建了,不然永远只显示当前年月的日期了
                divDom = document.querySelector('.calendar');
                if (!divDom) {
                    divDom = document.createElement('div');
                    divDom.className = 'calendar';
                    document.body.appendChild(divDom);
                }
                divDom.innerHTML = datepicker.buildUi(year, month);
            }

            datepicker.init = function(input) {
                datepicker.render();

                // 给输入框绑定事件,如果点击就显示或隐藏日历
                var $input = document.querySelector(input);
                var isOpen = false;
                $input.addEventListener('click', function() {
                    if (isOpen) {
                        divDom.classList.remove('calendar-show');
                        isOpen = false;
                    } else {
                        divDom.classList.add('calendar-show');
                        var left = $input.offsetLeft;
                        var top = $input.offsetTop;
                        var height = $input.offsetHeight;
                        divDom.style.left = left + 'px';
                        divDom.style.top = top + height + 2 + 'px';
                        isOpen = true;
                    }
                }, false);

                // 给左右按钮绑定单击事件,由于init方法只调用一次,而按钮每次都要重新渲染,所以如果直接绑定在按钮上会无效,因为按钮一直在销毁和重建,这里用事件代理
                divDom.addEventListener('click', function(e) {
                    var target = e.target;
                    if (!target.classList.contains('btn')) {
                        return;
                    }
                    if (target.classList.contains('btn-prev')) {
                        datepicker.render('prev');
                    }
                    if (target.classList.contains('btn-next')) {
                        datepicker.render('next');
                    }
                }, false);

                // 给每个日期绑定单击事件
                divDom.addEventListener('click', function(e) {
                    var target = e.target;
                    if (target.tagName.toLowerCase() !== 'td') {
                        return;
                    }
                    var date = new Date(monthData.year, monthData.month - 1, target.dataset.date);

                    $input.value = format(date);

                    // 点击之后隐藏日历
                    divDom.classList.remove('calendar-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;
            }

            // 全局注册一下
            window.datepicker = datepicker;
        })();

        datepicker.init('#datepicker');
    </script>
</body>

</html>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值