js日历选择控件

  快过年了,还有几天过年啊?天天看日历,所以,自己写了个日历选择器玩玩!

  直接上代码:

表现层

 1         #nickCalendar {
 2              250px;
 3             padding: 10px;
 4             text-align: center;
 5             background-color: springgreen;
 6             margin: auto;
 7             border-radius: 10px;
 8         }
 9 
10         .nick-calendar-tit {
11              168px;
12             margin: auto;
13             color: midnightblue;
14         }
15 
16         .nick-calendar-tit span {
17             float: left;
18              20px;
19             font-size: 14px;
20             height: 20px;
21             line-height: 20px;
22             text-align: center;
23             margin: 2px;
24             font-weight: bold;
25         }
26 
27         .nick-calendar-bd {
28              168px;
29             padding: 10px;
30             background-color: pink;
31             margin: auto;
32             border-radius: 10px;
33         }
34 
35         .clear:after {
36             content: '';
37             display: block;
38             height: 0;
39             clear: both;
40         }
41 
42         .nick-calendar-bd span {
43              20px;
44             font-size: 14px;
45             height: 20px;
46             line-height: 20px;
47             text-align: center;
48             margin: 2px;
49             float: left;
50             cursor: pointer;
51             border-radius: 50%;
52         }
53 
54         .prev-date-nick, .next-date-nick {
55             background-color: #999;
56         }
57 
58         .nick-calendar-hd {
59             height: 30px;
60             line-height: 30px;
61             font-weight: bold;
62         }
63 
64         .nick-calendar-prev, .nick-calendar-next {
65             background-color: violet;
66             border: 0;
67             border-radius: 5px;
68             font-weight: bold;
69         }
70 
71         .nick-calendar-prev-year, .nick-calendar-next-year {
72             background-color: turquoise;
73             border: 0;
74             border-radius: 5px;
75             font-weight: bold;
76         }
77 
78         .nick-calendar-date {
79             display: inline-block;
80              90px;
81         }
82 
83         .date-nick {
84             background-color: violet;
85         }
86 
87         .nick-calendar-current {
88             background-color: yellowgreen;
89         }
View Code

温馨提示:

  这点样式必须的哦,不然,呵呵!当然,你也可以自定义!

结构层

<input type="text" placeholder="请选择" readonly id="date1">

  结构层只需您一个触发容器input即可!

行为层

参数存在一个对象中

        var opt = {//参数保存在此对象中
            opts: options
        };

所有的方法保存在另一个对象中

        var obj = {}

填充日历方法

            fillDate: function (year, month) {}
  本月份第一天是星期几-为显示上个月的天数做铺垫
                var first_day = new Date(year, month, 1).getDay();

  如果刚好是星期天,则空出一行(显示上个月的天数)
                first_day = first_day == 0 ? 7 : first_day;

  本月份最后一天是几号
                var final_date = new Date(year, month + 1, 0).getDate(),

  上个月的最后一天是几号
                        last_date = new Date(year, month, 0).getDate(),

  剩余的格子数--即排在末尾的格子数
                        surplus = 42 - first_day - final_date;

  设置表头的日历
                opt.oHeadDate.innerHTML = year + '年' + (month + 1) + '月';

  填充日历内容
                var html = '';
                //上个月的显示天数
                for (var i = 0; i < first_day; i++) {
                    html += '<span class="prev-date-nick">' + (last_date - (first_day - 1) + i) + '</span>';
                }
                //本月的显示天数
                for (var j = 0; j < final_date; j++) {
                    html += '<span class="date-nick">' + (j + 1) + '</span>';
                }
                //下个月的显示天数
                for (var k = 0; k < surplus; k++) {
                    html += '<span class="next-date-nick">' + (k + 1) + '</span>';
                }
                //fill
                opt.oBody.innerHTML = html;

  设置当天样式
                if (year == new Date().getFullYear() && month == new Date().getMonth()) {
                    opt.oBody.getElementsByTagName('span')[first_day + opt.date - 1].className = 'nick-calendar-current date-nick';
                }

  点击赋值ipt得到日期
                for (var x = 0, v = opt.oBody.getElementsByTagName('span'), len = v.length; x < len; x++) {
                    v[x].onclick = function () {
                        var now = new Date(year, month, 1), y = 0, m = 0;
                        if (this.className.indexOf('prev-date-nick') > -1) {
                            y = new Date(now.setMonth(now.getMonth() - 1)).getFullYear();
                            m = new Date(now).getMonth();
                        } else if (this.className.indexOf('next-date-nick') > -1) {
                            y = new Date(now.setMonth(now.getMonth() + 1)).getFullYear();
                            m = new Date(now).getMonth();
                        } else if (this.className.indexOf('date-nick') > -1) {
                            y = year;
                            m = month;
                        }
                        document.getElementById('date1').value = y + '-' + (m + 1) + '-' + this.innerHTML;
                        opt.oWrap.style.display = 'none';//隐藏日历容器
                    }
                }

下个月

  就是设置月份加一即可。

            next: function () {
                var me = this;
                opt.oNext.onclick = function () {
                    opt.month++;
                    if (opt.month > 11) {
                        opt.month = 0;
                        opt.year++;
                    }
                    // 填充日历
                    me.fillDate(opt.year, opt.month);
                }

            },

上个月

  就是设置月份减一即可。

            prev: function () {
                var me = this;
                opt.oPrev.onclick = function () {
                    opt.month--;
                    if (opt.month < 0) {
                        opt.month = 11;
                        opt.year--;
                    }
                    // 填充日历
                    me.fillDate(opt.year, opt.month);
                }

            },

下一年

  就是设置年份加一即可。

            nextYear: function () {
                var me = this;
                opt.oNextYear.onclick = function () {
                    opt.year++;
                    // 填充日历
                    me.fillDate(opt.year, opt.month);
                }

            },

上一年

  就是设置年份减一即可。

            prevYear: function () {
                var me = this;
                opt.oPrevYear.onclick = function () {
                    if (opt.year > 1970) {
                        opt.year--;
                    }
                    // 填充日历
                    me.fillDate(opt.year, opt.month);
                }

            },

获取元素偏移位置

            offset: function (ele) {
                var l = ele.offsetLeft, t = ele.offsetTop, p = ele.offsetParent;
                while (p) {
                    l += p.offsetLeft + p.clientLeft;
                    t += p.offsetTop + p.clientTop;
                    p = p.offsetParent;
                }
                return {left: l, top: t}
            },

  用于设置日历容器样式定位。

初始化

            init: function () {//初始化
                }                

  初始化参数,创建日历容器固定结构,每次切换日期值即可

                var div = document.createElement("DIV");
                div.setAttribute('id', opt.opts.wrapId);
                div.innerHTML = '<div class="nick-calendar-hd"><button class="nick-calendar-prev-year">&lt;&lt;</button>' +
                        '<button class="nick-calendar-prev">&lt;</button><span class="nick-calendar-date"></span>' +
                        '<button class="nick-calendar-next">&gt;</button><button class="nick-calendar-next-year">&gt;&gt;</button>' +
                        '</div><div class="nick-calendar-tit clear">' +
                        '<span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>' +
                        '</div><div class="nick-calendar-bd clear"></div>';
                document.getElementsByTagName("body")[0].appendChild(div);
                opt.oWrap = document.getElementById(opt.opts.wrapId);//日历容器
                opt.trigger = document.getElementById(opt.opts.triggerId);//触发容器
                opt.oHeadDate = opt.oWrap.getElementsByClassName('nick-calendar-date')[0];//头部日期
                opt.oBody = opt.oWrap.getElementsByClassName('nick-calendar-bd')[0];//日期容器
                opt.oTit = opt.oWrap.getElementsByClassName('nick-calendar-tit')[0];//星期容器
                opt.oPrev = opt.oWrap.getElementsByClassName('nick-calendar-prev')[0];//上月按钮
                opt.oNext = opt.oWrap.getElementsByClassName('nick-calendar-next')[0];//下月按钮
                opt.oPrevYear = opt.oWrap.getElementsByClassName('nick-calendar-prev-year')[0];//上月按钮
                opt.oNextYear = opt.oWrap.getElementsByClassName('nick-calendar-next-year')[0];//下月按钮
                opt.year = 0;//年
                opt.month = 0;//月
                opt.date = 0;//日

获取今天的日历时间

                var now = new Date();
                opt.year = now.getFullYear();
                opt.month = now.getMonth();
                opt.date = now.getDate();

初始化--填充日历

                this.fillDate(opt.year, opt.month);

切换年月方法

                this.next();
                this.nextYear();
                this.prev();
                this.prevYear();

设置日历容器位置

                opt.oWrap.style.position = 'absolute';
                opt.oWrap.style.left = this.offset(opt.trigger).left + opt.trigger.offsetWidth + 10 + 'px';
                opt.oWrap.style.top = this.offset(opt.trigger).top + 'px';
                opt.oWrap.style.display = 'none';//默认隐藏日历容器

input触发日历选择

                opt.trigger.onclick = function () {
                    opt.oWrap.style.display = 'block';
                }

初始化调用

        obj.init();//初始化

定义日历选择方法

    function calendarNick(options) {
        var opt = {//参数保存在此对象中
            opts: options
        };
        var obj={
    //code
        };      
}  

  定义一个日历选择器方法把2个对象包裹起来,并调用初始化方法即可。

调用日历选择器

  调用时,两个必传的容器id参数。

    calendarNick({
        wrapId: 'nickCalendar',//日历容器id
        triggerId: 'date1'//触发容器id
    });

  完整代码:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>calendar-nick</title>
  6     <style>
  7         #nickCalendar {
  8              250px;
  9             padding: 10px;
 10             text-align: center;
 11             background-color: springgreen;
 12             margin: auto;
 13             border-radius: 10px;
 14         }
 15 
 16         .nick-calendar-tit {
 17              168px;
 18             margin: auto;
 19             color: midnightblue;
 20         }
 21 
 22         .nick-calendar-tit span {
 23             float: left;
 24              20px;
 25             font-size: 14px;
 26             height: 20px;
 27             line-height: 20px;
 28             text-align: center;
 29             margin: 2px;
 30             font-weight: bold;
 31         }
 32 
 33         .nick-calendar-bd {
 34              168px;
 35             padding: 10px;
 36             background-color: pink;
 37             margin: auto;
 38             border-radius: 10px;
 39         }
 40 
 41         .clear:after {
 42             content: '';
 43             display: block;
 44             height: 0;
 45             clear: both;
 46         }
 47 
 48         .nick-calendar-bd span {
 49              20px;
 50             font-size: 14px;
 51             height: 20px;
 52             line-height: 20px;
 53             text-align: center;
 54             margin: 2px;
 55             float: left;
 56             cursor: pointer;
 57             border-radius: 50%;
 58         }
 59 
 60         .prev-date-nick, .next-date-nick {
 61             background-color: #999;
 62         }
 63 
 64         .nick-calendar-hd {
 65             height: 30px;
 66             line-height: 30px;
 67             font-weight: bold;
 68         }
 69 
 70         .nick-calendar-prev, .nick-calendar-next {
 71             background-color: violet;
 72             border: 0;
 73             border-radius: 5px;
 74             font-weight: bold;
 75         }
 76 
 77         .nick-calendar-prev-year, .nick-calendar-next-year {
 78             background-color: turquoise;
 79             border: 0;
 80             border-radius: 5px;
 81             font-weight: bold;
 82         }
 83 
 84         .nick-calendar-date {
 85             display: inline-block;
 86              90px;
 87         }
 88 
 89         .date-nick {
 90             background-color: violet;
 91         }
 92 
 93         .nick-calendar-current {
 94             background-color: yellowgreen;
 95         }
 96 
 97     </style>
 98 </head>
 99 <body>
100 <input type="text" placeholder="请选择" readonly id="date1">
101 <script>
102     //        调用
103     calendarNick({
104         wrapId: 'nickCalendar',//日历容器id
105         triggerId: 'date1'//触发容器id
106     });
107     //日历选择功能
108     function calendarNick(options) {
109         var opt = {//参数保存在此对象中
110             opts: options
111         };
112 
113         var obj = {
114             //填充日历
115             fillDate: function (year, month) {
116                 //本月份第一天是星期几-为显示上个月的天数做铺垫
117                 var first_day = new Date(year, month, 1).getDay();
118                 //如果刚好是星期天,则空出一行(显示上个月的天数)
119                 first_day = first_day == 0 ? 7 : first_day;
120                 //本月份最后一天是几号
121                 var final_date = new Date(year, month + 1, 0).getDate(),
122                 //上个月的最后一天是几号
123                         last_date = new Date(year, month, 0).getDate(),
124                 //剩余的格子数--即排在末尾的格子数
125                         surplus = 42 - first_day - final_date;
126                 /*设置表头的日历*/
127                 opt.oHeadDate.innerHTML = year + '年' + (month + 1) + '月';
128                 /*填充日历执行*/
129                 var html = '';
130                 //上个月的显示天数
131                 for (var i = 0; i < first_day; i++) {
132                     html += '<span class="prev-date-nick">' + (last_date - (first_day - 1) + i) + '</span>';
133                 }
134                 //本月的显示天数
135                 for (var j = 0; j < final_date; j++) {
136                     html += '<span class="date-nick">' + (j + 1) + '</span>';
137                 }
138                 //下个月的显示天数
139                 for (var k = 0; k < surplus; k++) {
140                     html += '<span class="next-date-nick">' + (k + 1) + '</span>';
141                 }
142                 //fill
143                 opt.oBody.innerHTML = html;
144                 // 当天
145                 if (year == new Date().getFullYear() && month == new Date().getMonth()) {
146                     opt.oBody.getElementsByTagName('span')[first_day + opt.date - 1].className = 'nick-calendar-current date-nick';
147                 }
148 
149                 //点击赋值ipt得到日期
150                 for (var x = 0, v = opt.oBody.getElementsByTagName('span'), len = v.length; x < len; x++) {
151                     v[x].onclick = function () {
152                         var now = new Date(year, month, 1), y = 0, m = 0;
153                         if (this.className.indexOf('prev-date-nick') > -1) {
154                             y = new Date(now.setMonth(now.getMonth() - 1)).getFullYear();
155                             m = new Date(now).getMonth();
156                         } else if (this.className.indexOf('next-date-nick') > -1) {
157                             y = new Date(now.setMonth(now.getMonth() + 1)).getFullYear();
158                             m = new Date(now).getMonth();
159                         } else if (this.className.indexOf('date-nick') > -1) {
160                             y = year;
161                             m = month;
162                         }
163                         document.getElementById('date1').value = y + '-' + (m + 1) + '-' + this.innerHTML;
164                         opt.oWrap.style.display = 'none';//隐藏日历容器
165                     }
166                 }
167             },
168             // 下个月
169             next: function () {
170                 var me = this;
171                 opt.oNext.onclick = function () {
172                     opt.month++;
173                     if (opt.month > 11) {
174                         opt.month = 0;
175                         opt.year++;
176                     }
177                     // 填充日历
178                     me.fillDate(opt.year, opt.month);
179                 }
180 
181             },
182             // 上个月
183             prev: function () {
184                 var me = this;
185                 opt.oPrev.onclick = function () {
186                     opt.month--;
187                     if (opt.month < 0) {
188                         opt.month = 11;
189                         opt.year--;
190                     }
191                     // 填充日历
192                     me.fillDate(opt.year, opt.month);
193                 }
194 
195             },
196             // 下一年
197             nextYear: function () {
198                 var me = this;
199                 opt.oNextYear.onclick = function () {
200                     opt.year++;
201                     // 填充日历
202                     me.fillDate(opt.year, opt.month);
203                 }
204 
205             },
206             // 上一年
207             prevYear: function () {
208                 var me = this;
209                 opt.oPrevYear.onclick = function () {
210                     if (opt.year > 1970) {
211                         opt.year--;
212                     }
213                     // 填充日历
214                     me.fillDate(opt.year, opt.month);
215                 }
216 
217             },
218             //获取元素偏移位置
219             offset: function (ele) {
220                 var l = ele.offsetLeft, t = ele.offsetTop, p = ele.offsetParent;
221                 while (p) {
222                     l += p.offsetLeft + p.clientLeft;
223                     t += p.offsetTop + p.clientTop;
224                     p = p.offsetParent;
225                 }
226                 return {left: l, top: t}
227             },
228             init: function () {//初始化
229                 //  初始化参数
230                 //创建日历容器固定结构,每次切换日期值即可
231                 var div = document.createElement("DIV");
232                 div.setAttribute('id', opt.opts.wrapId);
233                 div.innerHTML = '<div class="nick-calendar-hd"><button class="nick-calendar-prev-year">&lt;&lt;</button>' +
234                         '<button class="nick-calendar-prev">&lt;</button><span class="nick-calendar-date"></span>' +
235                         '<button class="nick-calendar-next">&gt;</button><button class="nick-calendar-next-year">&gt;&gt;</button>' +
236                         '</div><div class="nick-calendar-tit clear">' +
237                         '<span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>' +
238                         '</div><div class="nick-calendar-bd clear"></div>';
239                 document.getElementsByTagName("body")[0].appendChild(div);
240                 opt.oWrap = document.getElementById(opt.opts.wrapId);//日历容器
241                 opt.trigger = document.getElementById(opt.opts.triggerId);//触发容器
242                 opt.oHeadDate = opt.oWrap.getElementsByClassName('nick-calendar-date')[0];//头部日期
243                 opt.oBody = opt.oWrap.getElementsByClassName('nick-calendar-bd')[0];//日期容器
244                 opt.oTit = opt.oWrap.getElementsByClassName('nick-calendar-tit')[0];//星期容器
245                 opt.oPrev = opt.oWrap.getElementsByClassName('nick-calendar-prev')[0];//上月按钮
246                 opt.oNext = opt.oWrap.getElementsByClassName('nick-calendar-next')[0];//下月按钮
247                 opt.oPrevYear = opt.oWrap.getElementsByClassName('nick-calendar-prev-year')[0];//上月按钮
248                 opt.oNextYear = opt.oWrap.getElementsByClassName('nick-calendar-next-year')[0];//下月按钮
249                 opt.year = 0;//年
250                 opt.month = 0;//月
251                 opt.date = 0;//日
252 
253                 // 获取今天的日历时间
254                 var now = new Date();
255                 opt.year = now.getFullYear();
256                 opt.month = now.getMonth();
257                 opt.date = now.getDate();
258                 // 初始化--填充日历
259                 this.fillDate(opt.year, opt.month);
260                 //切换年月
261                 this.next();
262                 this.nextYear();
263                 this.prev();
264                 this.prevYear();
265                 //设置日历容器位置
266                 opt.oWrap.style.position = 'absolute';
267                 opt.oWrap.style.left = this.offset(opt.trigger).left + opt.trigger.offsetWidth + 10 + 'px';
268                 opt.oWrap.style.top = this.offset(opt.trigger).top + 'px';
269                 opt.oWrap.style.display = 'none';//默认隐藏日历容器
270                 //ipt触发日历选择
271                 opt.trigger.onclick = function () {
272                     opt.oWrap.style.display = 'block';
273                 }
274             }
275         };
276         obj.init();//初始化
277     }
278 
279 </script>
280 </body>
281 </html>
View Code

  over!注释加代码应该一看就懂了。复制完整代码,试试吧!

  周公找我了,see you!

 
 
原文地址:https://www.cnblogs.com/puyongsong/p/6348038.html