仿win7日历插件

文本框日历是个老生常谈的问题,虽然html5有了input[type=‘date‘],但是各大浏览器厂商对html5的支持并未统一,所以实际开发中大多还是用js实现。这是一款基于jq(本来打算用原生JavaScript,写着写着就用到了jq,以后有时间再改吧~)、依赖外部样式的插件,模仿的win7日历UI。

样式如下(可以按需修改):

好了不废话了,代码如下:

JavaScript:

var DatePicker = (function() {
    var params = {};
    //根据年、月返回月天数
    function getDays(year,month) {
        var days = 30,
            isLeapYear = false;
        //年份能被4整除且不能被100整除,或能被100整除且能被400整除,为闰年
        if((year%4==0 && year%100!=0)||(year%100==0 && year%400==0)) isLeapYear = true;
        switch(month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
            days = 31;
            break;
            case 2 :
            isLeapYear ? days = 29 : days = 28;
            break;
        }
        return days;
    };
    //根据年、月、日返回星期X
    function getDayIndex(year,month,day) {
        return new Date(year,month-1,day).getDay();
    };
    //初始化UI
    function initUI(o) {
        var shell = document.createElement(‘div‘),  //日历框
            shellCtrl = document.createElement(‘div‘),  //年月选择器
            shellWeek = document.createElement(‘p‘),  //week
            shellDates = document.createElement(‘ul‘),  //日期标签
            shellMonths = document.createElement(‘ul‘), //月标签
            shellYears = document.createElement(‘ul‘),  //年份标签
            curDate = new Date(),  //当前时间
            cName =  o.cName,  //日历框className
            yearId = cName + ‘-year‘,
            monthId = cName + ‘-month‘,
            choseId = cName + ‘-chose‘,
            choseYearsId = cName + ‘-years‘,
            prevBtnId = cName + ‘-prev‘,
            nextBtnId = cName + ‘-next‘,
            shellId = ‘J-‘ + cName;
        shell.className = cName;
        shell.id = shellId;
        shellCtrl.innerHTML = ‘<a href="javascript:;" id=‘+ prevBtnId +‘ class=‘+ cName +‘-prev><</a><span id=‘+ choseId +‘ view="date"><span id=‘+ yearId +‘>‘+ curDate.getFullYear() +‘年</span><span id=‘+ monthId +‘>‘+ (curDate.getMonth()+1) +‘月</span></span><span style="display:none" id=‘+ choseYearsId +‘>2010-2019</span><a href="javascript:;" id=‘+ nextBtnId +‘ class=‘+ cName +‘-next>></a>‘;
        shellWeek.innerHTML = ‘<span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>‘;
        shellDates.className = cName + ‘-dates‘;
        shellMonths.className = cName + ‘-months‘;
        shellYears.className = cName + ‘-years‘;
        shellYears.style.display = ‘none‘;
        shellMonths.innerHTML = ‘<li>一月</li><li>二月</li><li>三月</li><li>四月</li><li>五月</li><li>六月</li><li>七月</li><li>八月</li><li>九月</li><li>十月</li><li>十一月</li><li>十二月</li>‘;
        //添加主要html结构
        shell.appendChild(shellCtrl);
        shell.appendChild(shellWeek);
        shell.appendChild(shellDates);
        shell.appendChild(shellMonths);
        shell.appendChild(shellYears);
        document.body.appendChild(shell);
        params = $.extend(params,{
            oYear : document.getElementById(yearId),
            oMonth : document.getElementById(monthId),
            oChose : document.getElementById(choseId),
            oChoseYears : document.getElementById(choseYearsId),
            oShell : shell,
            shellId : shellId,
            oDates : shellDates,
            oMonths : shellMonths,
            oWeeks : shellWeek,
            oYears : shellYears,
            prevBtn : document.getElementById(prevBtnId),
            nextBtn : document.getElementById(nextBtnId)
        });
        fillDates(parseInt(document.getElementById(yearId).innerHTML),parseInt(document.getElementById(monthId).innerHTML));
        //下划线突出当前日期
        for(var i = 0; i < shellDates.getElementsByTagName(‘li‘).length; i ++) {
            if(!shellDates.getElementsByTagName(‘li‘)[i].getAttribute(‘date‘)) continue;
            if(shellDates.getElementsByTagName(‘li‘)[i].getAttribute(‘date‘).match(/\d*$/)[0] == new Date().getDate()) {
                shellDates.getElementsByTagName(‘li‘)[i].style.fontWeight = ‘bold‘;
            }
        }
        clickDay(o.elem);
    };
    //根据年月填充日期 共42个数字
    function fillDates(year,month) {
        var datesContain = document.getElementsByTagName(‘ul‘)[0],
            start = getDayIndex(year,month,1), //获取当前年月第一天的星期下标
            prevMonthDays = getDays(year,month - 1),  //获取上个月天数
            curMonthDays = getDays(year,month),
            htmlStr = ‘‘,
            n = 1,
            j = 1;
        prevMonthDays = month==1 ? 31 : prevMonthDays;
        start = start==0 ? 7 : start;
        for(var i = prevMonthDays - start + 1; i <= prevMonthDays; i++) {
            htmlStr += ‘<li class="prev">‘+ i +‘</li>‘;
        }
        while(n <= curMonthDays) {
            htmlStr += ‘<li date=‘+ year +‘-‘+ month +‘-‘+ n +‘>‘+ n +‘</li>‘;
            n ++;
        }
        while(j <= 42-start-curMonthDays) {
            htmlStr += ‘<li class="next">‘+ j +‘</li>‘;
            j ++;
        }
        datesContain.innerHTML = htmlStr;
    };
    //填充年份集合
    function fillYears() {
        var start = params.oChoseYears.innerHTML.split(‘-‘)[0] - 0,
            end1 = params.oChoseYears.innerHTML.split(‘-‘)[1]- 0,
            htmlStr = ‘‘;
        params.oYears.innerHTML = ‘‘;
         htmlStr = ‘<li class="prev">‘+ (start-1) +‘</li>‘
         while(start <= end1) {
             htmlStr += ‘<li year=‘+ start +‘>‘+ start +‘</li>‘;
             start ++;
         }
         htmlStr += ‘<li class="next">‘+ start +‘</li>‘;
         params.oYears.innerHTML = htmlStr;
    };
    //事件集合
    function bind(o) {
        //切换月份/日期视图
        params.oChose.onclick = function() {
             var view = this.getAttribute(‘view‘);
             if(view == ‘date‘) {
                 params.oDates.style.display = ‘none‘;
                 params.oWeeks.style.display = ‘none‘;
                 params.oMonths.style.display = ‘block‘;
                 this.setAttribute(‘view‘,‘month‘);
                 params.oMonth.style.display = ‘none‘;
             } else if(view == ‘month‘) {
                 var year = parseInt(params.oYear.innerHTML),
                     singular = String(year).match(/\d$/);
                     start = year -singular -1,
                     end = start+10,
                     htmlStr = ‘‘;
                 params.oChoseYears.innerHTML = (start+1) + ‘-‘ + end;
                 htmlStr = ‘<li class="prev">‘+ start +‘</li>‘
                 while(start+1 <= end) {
                     htmlStr += ‘<li year=‘+ (start+1) +‘>‘+ (start+1) +‘</li>‘;
                     start ++;
                 }
                 htmlStr += ‘<li class="next">‘+ (start+1) +‘</li>‘;
                 params.oYears.innerHTML = htmlStr;
                 clickYear();
                 params.oDates.style.display = ‘none‘;
                 params.oWeeks.style.display = ‘none‘;
                 params.oMonths.style.display = ‘none‘;
                 this.setAttribute(‘view‘,‘year‘);
                 params.oChose.style.display = ‘none‘;
                 params.oChoseYears.style.display = ‘‘;
                 params.oYears.style.display = ‘block‘;
             }
        };
        //点击年集合
        params.oChoseYears.onclick = function() {
            this.style.display = ‘none‘;
            params.oChose.style.display = ‘‘;
            params.oChose.setAttribute(‘view‘,‘date‘);
            params.oMonth.style.display = ‘‘;
            params.oDates.style.display = ‘block‘;
            params.oMonths.style.display = ‘none‘;
            params.oYears.style.display = ‘none‘;
            params.oWeeks.style.display = ‘block‘;
        };
        //点击月份
        var n = 0;
        while(n < 12) {
            params.oMonths.getElementsByTagName(‘li‘)[n].onclick = function() {
                switch(this.innerHTML) {
                    case ‘一月‘ :
                    params.oMonth.innerHTML = ‘1月‘;
                    break;
                    case ‘二月‘ :
                    params.oMonth.innerHTML = ‘2月‘;
                    break;
                    case ‘三月‘ :
                    params.oMonth.innerHTML = ‘3月‘;
                    break;
                    case ‘四月‘ :
                    params.oMonth.innerHTML = ‘4月‘;
                    break;
                    case ‘五月‘ :
                    params.oMonth.innerHTML = ‘5月‘;
                    break;
                    case ‘六月‘ :
                    params.oMonth.innerHTML = ‘6月‘;
                    break;
                    case ‘七月‘ :
                    params.oMonth.innerHTML = ‘7月‘;
                    break;
                    case ‘八月‘ :
                    params.oMonth.innerHTML = ‘8月‘;
                    break;
                    case ‘九月‘ :
                    params.oMonth.innerHTML = ‘9月‘;
                    break;
                    case ‘十月‘ :
                    params.oMonth.innerHTML = ‘10月‘;
                    break;
                    case ‘十一月‘ :
                    params.oMonth.innerHTML = ‘11月‘;
                    break;
                    case ‘十二月‘ :
                    params.oMonth.innerHTML = ‘12月‘;
                    break;
                }
                params.oMonth.style.display = ‘‘;
                params.oMonths.style.display = ‘none‘;
                params.oDates.style.display = ‘block‘;
                params.oWeeks.style.display = ‘block‘;
                params.oChose.setAttribute(‘view‘,‘date‘);
                fillDates(parseInt(params.oYear.innerHTML),parseInt(params.oMonth.innerHTML));
                clickDay(o.elem);
            };
            n ++;
        }
        //点击左按钮
        params.prevBtn.onclick = function() {
            var view = params.oChose.getAttribute(‘view‘);
            if(view == ‘date‘) {
                var year = parseInt(params.oYear.innerHTML),
                    month = parseInt(params.oMonth.innerHTML);
                if(month > 1) {
                    params.oMonth.innerHTML = --month + ‘月‘;
                } else {
                    params.oYear.innerHTML = --year + ‘年‘;
                    params.oMonth.innerHTML = 12 + ‘月‘;
                }
            } else if(view == ‘year‘) {
                var yearStart = params.oChoseYears.innerHTML.split(‘-‘)[0],
                    yearStart = yearStart - 10,
                    yearEnd = yearStart + 9;
                params.oChoseYears.innerHTML = yearStart + ‘-‘ + yearEnd;
                fillYears();
                clickYear();
            }
            else {
                var year = parseInt(params.oYear.innerHTML);
                params.oYear.innerHTML = --year + ‘年‘;
            }
            fillDates(parseInt(params.oYear.innerHTML),parseInt(params.oMonth.innerHTML));
            clickDay(o.elem);
        };
        //点击右按钮
        params.nextBtn.onclick = function() {
            var view = params.oChose.getAttribute(‘view‘);
            if(view == ‘date‘) {
                var year = parseInt(params.oYear.innerHTML),
                    month = parseInt(params.oMonth.innerHTML);
                if(month < 12) {
                    params.oMonth.innerHTML = ++month + ‘月‘;
                } else {
                    params.oYear.innerHTML = ++year + ‘年‘;
                    params.oMonth.innerHTML = 1 + ‘月‘;
                }
            } else if(view == ‘year‘) {
                var yearStart = params.oChoseYears.innerHTML.split(‘-‘)[0] - 0,
                    yearStart = yearStart + 10,
                    yearEnd = yearStart + 9;
                params.oChoseYears.innerHTML = yearStart + ‘-‘ + yearEnd;
                fillYears();
                clickYear();
            } else {
                var year = parseInt(params.oYear.innerHTML);
                params.oYear.innerHTML = ++year + ‘年‘;
            }
            fillDates(parseInt(params.oYear.innerHTML),parseInt(params.oMonth.innerHTML));
            clickDay(o.elem);
        };
        document.body.onclick = function() {
            if(document.getElementById(params.shellId)) document.body.removeChild(params.oShell);
        };
        $(‘#‘+params.shellId).click(function(e){
            e && e.stopPropagation ?  e.stopPropagation() : e.cancelBubble=true;
        });
    };
    //单击日期
    function clickDay(elem) {
        var m = 0,
            dayList = params.oDates.getElementsByTagName(‘li‘);
        while(m < dayList.length) {
            dayList[m].onclick = function() {
                if(!this.getAttribute(‘date‘)) return false;
                elem.value = this.getAttribute(‘date‘);
                document.body.removeChild(params.oShell);
            };
            m ++;
        }
    };
    //点击年份
    function clickYear() {
        //点击年份
        var yearStart = 0;
        while(yearStart < 12) {
            params.oYears.getElementsByTagName(‘li‘)[yearStart].onclick = function() {
                if(!this.getAttribute(‘year‘)) return false;
                var year = this.innerHTML;
                params.oChose.style.display = ‘‘;
                params.oChose.setAttribute(‘view‘,‘month‘);
                params.oYear.innerHTML = year + ‘年‘;
                params.oYears.style.display = ‘none‘;
                params.oChoseYears.style.display = ‘none‘;
                params.oMonths.style.display = ‘block‘;
            };
            yearStart ++;
        }
    };
    var O = function() {};
    O.prototype.init = function(config) {
        this.elem = document.getElementById(config.id);
        this.cName = config.cName;
        var _this = this;
        var st;
        $(‘#‘+config.id).click(function(e){
            e && e.stopPropagation ?  e.stopPropagation() : e.cancelBubble=true;
            if(document.getElementById(params.shellId)) document.body.removeChild(params.oShell);
            initUI(_this);
            var left = $(this).offset().left,
                top = $(this).offset().top,
                h = $(this).outerHeight(),
                bH = $(‘body‘).height(),
                oSH = params.oShell.offsetHeight;
            params.oShell.style.left = left + ‘px‘;
            params.oShell.style.top = (top+h) + ‘px‘;
            if(bH-top-h < oSH) {
                params.oShell.style.top =(top-oSH) + ‘px‘;
            }
            //绑定事件
            bind(_this);
        });
    };
    return O;
})();

Html+Css(注意要先引用jquery):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>日期控件</title>
</head>
<script src="JavaScript/jquery-1.8.3.min.js"></script>
<link rel="stylesheet" type="text/css" charset="utf-8" href="Css/public.css">
<style>

  *{margin:0;padding:0;}
  a{text-decoration:none;}
  input{height:30px;line-height:30px;}
  body{color:#f63;font-size:16px;line-height:22px;}
  ul,li{list-style:none;}
  /*控件样式*/
  .datePicker{background:#fff;width:161px;padding:7px;border:1px solid #ddd;position:absolute;top:0;left:0;color:#000;font-size:12px;}
  .datePicker div{height:25px;line-height:25px;text-align:center;position:relative;border-bottom:1px solid #d8d8d8;font-size:14px;}
  .datePicker div a{position:absolute;top:0;text-align:center;line-height:25px;font-size:18px;font-family:sumsin;color:;}
  .datePicker div span{cursor:pointer;}
  .datePicker p {line-height:25px;}
  .datePicker p span{display:inline-block;width:23px;text-align:center;}
  .datePicker-prev{left:0;}
  .datePicker-next{right:0;}
  .datePicker-months{display:none;}
  .datePicker-months li{cursor:pointer;width:40px;float:left;text-align:center;line-height:49px;}
  .datePicker-months li:hover{color:#e7bb70;}
  .datePicker-dates{height:132px;overflow:hidden;}
  .datePicker-dates li{width:23px;height:22px;line-height:22px;float:left;text-align:center;cursor:pointer;}
  .datePicker-dates li:hover{color:#e7bb70;}
  .datePicker-dates .prev,.datePicker-dates .next{color:#999;cursor:not-allowed;}
  .datePicker-dates .prev:hover,.datePicker-dates .next:hover{color:#999;;}
  .datePicker-years{height:132px;}
  .datePicker-years li{line-height:49px;text-align:center;width:25%;float:left;cursor:pointer;}
  .datePicker-years .prev,.datePicker-years .next{color:#999;cursor:not-allowed;}
  /*控件样式*/
  .myDatePicker{background:#f4f4f4;width:161px;padding:7px;border:1px solid #ccc;position:absolute;top:0;left:0;color:#000;font-size:12px;font-family:‘Microsoft Yahei‘;}
  .myDatePicker div{height:25px;line-height:25px;text-align:center;position:relative;border-bottom:1px solid #d8d8d8;font-size:14px;}
  .myDatePicker div a{position:absolute;top:0;text-align:center;line-height:25px;font-size:18px;font-family:sumsin;color:;}
  .myDatePicker div span{cursor:pointer;}
  .myDatePicker p {line-height:25px;}
  .myDatePicker p span{display:inline-block;width:23px;text-align:center;}
  .myDatePicker-prev{left:0;}
  .myDatePicker-next{right:0;}
  .myDatePicker-months{display:none;}
  .myDatePicker-months li{cursor:pointer;width:40px;float:left;text-align:center;line-height:49px;}
  .myDatePicker-months li:hover{color:#f63;}
  .myDatePicker-dates{height:132px;overflow:hidden;}
  .myDatePicker-dates li{width:23px;height:22px;line-height:22px;float:left;text-align:center;cursor:pointer;}
  .myDatePicker-dates li:hover{color:#f63;}
  .myDatePicker-dates .prev,.myDatePicker-dates .next{color:#999;cursor:not-allowed;}
  .myDatePicker-dates .prev:hover,.myDatePicker-dates .next:hover{color:#999;;}
  .myDatePicker-years{height:132px;}
  .myDatePicker-years li{line-height:49px;text-align:center;width:25%;float:left;cursor:pointer;}
  .myDatePicker-years .prev,.myDatePicker-years .next{color:#999;cursor:not-allowed;}
</style>
<body>
<h1 style="color:#555;line-height:50px;">仿windows7系统日期控件,依赖jQuery、外部样式!</h1>
<div style="position:relative;height:100px;border:5px solid #ddd;margin:10px;overflow:hidden;">
    1、input绝对定位,父级相对定位&溢出隐藏。
    <input type="text" id="ipt" style="position:absolute;top:70px;left:100px;">
</div>
<div style="height:300px;margin:10px;background:#f4f4f4;"></div>
2、盒模型input,相对定位,有padding、margin、border
  <input type="text" id="ipt1" style="position:relative;left:22px;margin:10px;padding:5px;">
  <div style="height:200px;"></div>
  3、父级标签为body,当文本框距底高度不足以完全显示,则定位在文本框上方。
  <input  type="text" id="ipt2">
  <br>
  你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊<br>你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊你好啊<br>
<script>
//参数cName为控件外层class名,方便自定义样式名称
new DatePicker().init({id : ‘ipt‘,cName : ‘datePicker‘});
new DatePicker().init({id : ‘ipt1‘,cName : ‘myDatePicker‘});
new DatePicker().init({id : ‘ipt2‘,cName : ‘datePicker‘});

</script>
</body>
</html>
时间: 2024-10-15 13:59:25

仿win7日历插件的相关文章

javascript日历插件

最近在尝试着写javascript日历插件,所以也到github上看国外人日历源码,或者国内人写的好点的,也在研究点,虽然看到网上有一大把的日历控件,但是没有几个是自己想要的,虽然效果是实现了,但是看他们的源码,头有点大,所以自己也在研究这方面的东西.周末用了2天来研究别人写的代码 自己也试着做做demo,今天正好基本功能完成了,所以趁着这个机会分享下:我们可以先来看看效果:JSFiddler地址如下: demo链接请点击我 基本的配置如下:    targetCls '',    输入框dom

Kalendae——一款功能强大的日历插件

url:http://zjingwen.github.io/SetTimeOutGoBlog/kalendae/index.html (如果打开过慢,或者打不开,原因你懂得.) 一.Kalendae--一款功能强大的日历插件,英文版的,我英文太渣,有没有找到,中文文档.只能自己慢慢翻译,鼓捣了. 二.基本信息 Kalendae支持多种日历样式,可双联.单联.多联,支持单选日期,多选日期.联排选择.跨月选择.而且依赖图片极少,对于使用css来重构UI界面,非常有利. 依赖于了kaledae.js.

根据一篇js日历插件改写的

1 <!-- 2 控件调用示例: 3 --> 4 5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 6 7 <html xmlns="http://www.w3.org/1999/xhtml"> 8 9 <he

【UI插件】简单的日历插件(下)—— 学习MVC思想

前言 我们上次写了一个简单的日历插件,但是只是一个半成品,而且做完后发现一些问题,于是我们今天尝试来解决这些问题 PS:距离上次貌似很久了 上次,我们大概遇到哪些问题呢: ① 既然想做一套UI库,那么就应该考虑其它UI库的接入问题 这个意思就是,我们的系统中所有UI插件应该有一些统一行为,我们如果希望统一为所有的插件加一点什么东西,需要有位置可加 这个意味着,可能我们所有的插件需要继承至一个抽象的UI类,并且该类提供了通用的几个事件点 ② 上次做的日历插件虽然说是简单,其耦合还是比较严重的(其实

基于jQuery的日历插件

上个星期看到同事做一个有关日历提醒功能的需求,为了找个插件也是费了不少心思,然后刚好有时间就试着写了一个简单demo 来看下最终效果图吧: 是长得丑了一点,不要吐槽我-.- 首先来说说这个日历主要的制作逻辑吧: ·一个月份最多有31天,需要一个7X6的表格去装载 ·如果知道了某个月份1号是星期几,这个月份有多少天,一个循环就可以显示某个月的日历了吧(眼睛都放光了*.*) ·加上一些控件让用户可以方便操作吧(比如可以输入年份.月份,可以点击选择年份.月份) 新建一个html文件,html结构: <

java仿win7计算器布局

代码: package calculator; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class cal extends JFrame{ private JTextField tf =new JTextField("0"); public void addButton(String name,GridBagLayout g ,GridBagConstraints c){ JBut

Android应用源码之仿墨迹天气插件

Android应用源码之仿墨迹天气插件 仿照墨迹天气的桌面小插件例子源码. 下载地址:http://www.dwz.cn/Cox82 运行截图:

JavaScript之jQuery-7 jQuery 使用插件(使用插件、日历插件、表单验证插件)

一.jQuery 使用插件 插件的查找与帮助 - jQuery 官方网站的插件库(http://plugins.jquery.com) 提供了大量的插件.并给出去了每个插件的用户评级.版本及bug等 - 库中列出了每个插件的ZIP文件下载.演示.示例代码及教程 使用插件 - step 1:将插件包导入到页面中,并确保它在jQuery源文件之后 <script src="jqeury-1.11.1.js"></script> <script></

重写的HTML5酒店入住日期选择日历插件

<!DOCTYPE HTML><html lang="zh-CN"><head><title>接触角测定仪</title><script src="http://www.codefans.net/ajaxjs/jquery-1.6.2.min.js" type="application/javascript" language="javascript">&