码迷,mamicode.com
首页 > Windows程序 > 详细

仿win7日历插件

时间:2015-11-23 10:04:01      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

文本框日历是个老生常谈的问题,虽然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>

 

仿win7日历插件

标签:

原文地址:http://www.cnblogs.com/tianpw/p/4987430.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!