日历控件源码

前两天需要个简单的日历控件,网上搜了一下居然还有人卖,估计是提供其他维护服务吧,反正我是用不到的,自己手写了个凑合用,自己写的兼容性没测过,如果有什么问题大家给点改进意见。

先上图

源码

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>

    <script type="text/javascript">

        //星期列表
        var WEEK = ["日","一","二","三","四","五","六"];
        //平年每月天数
        var DAYS_IN_NORMAL = [31,28,31,30,31,30,31,31,30,31,30,31];
        //闰年每月天数
        var DAYS_IN_SPECIAL = [31,29,31,30,31,30,31,31,30,31,30,31];
        //选择年份每月天数
        var DAYS_IN_SELECTED;
        //存放日期的输入框
        var CONTAINER;
        //日期分隔符
        var SPLIT;
        //日历界面
        var DATE_PANEL;
        //选定的日期,默认为当天
        var DEFAULT_DATE = new Date();

        /**
         * 日期控件入口,主要控制div层显示和隐藏
         * @param inputId 日期输入框ID
         * @param split   日期分隔符
         */
        function selectDate(inputId,split)
        {
            SPLIT = split;
            CONTAINER = document.getElementById(inputId);
            DATE_PANEL = document.getElementById("div_"+inputId);

            //获取日期输入框位置(x,y)
            var x = CONTAINER.clientLeft;
            var y = CONTAINER.clientTop + CONTAINER.clientHeight;
            var strDate = CONTAINER.value.trim();

            //设定日历的日期
            if(strDate != "")
            {
                var ymd = changeStr2ArrDate(strDate);

                if(ymd.length==3)
                {
                    DEFAULT_DATE.setFullYear(parseInt(ymd[0]));
                    DEFAULT_DATE.setMonth(parseInt(ymd[1])-1);
                    DEFAULT_DATE.setDate(parseInt(ymd[2]));
                }
                else
                {
                    alert("输入日期格式不正确");
                    return "";
                }
            }

            if(DATE_PANEL.style.display=="none")
            {
                DATE_PANEL.style.border = "1px solid black";
                DATE_PANEL.style.backgroundColor = "aliceblue";
                DATE_PANEL.style.width = "175px";
                DATE_PANEL.style.height = "160px";
                DATE_PANEL.style.position = "fixed";
                DATE_PANEL.style.zIndex = "99";
                DATE_PANEL.style.marginLeft = x;
                DATE_PANEL.style.marginTop = y;
                DATE_PANEL.innerHTML = datePanel();
                DATE_PANEL.style.display = "block";
            }
            else
            {
                DATE_PANEL.style.display = "none";
            }
        }

        /**
         * 将字符串日期转数组存储
         *
         * @param strDate
         * @returns {array} 三位长度数组,分别对应年月日
         */
        function changeStr2ArrDate(strDate)
        {
            var arr;
            if(SPLIT == "-" && strDate.substr(0,1) == "-")
            {
                arr =  strDate.substr(1).split(SPLIT);
                if(arr.length>1)
                {
                    arr[0] = "-" + arr[0];
                }
            }
            else
            {
                arr = strDate.split(SPLIT);
            }

            if(arr.length==3 && parseInt(arr[1])>0 &&  parseInt(arr[1]) < 13 && parseInt(arr[2])>0 &&  parseInt(arr[2]) <= parseInt(DAYS_IN_SELECTED[parseInt(arr[1])]))
            {
               return arr;
            }
            else
            {
                return new Array();
            }
        }

        /**
         * 根据输入字符串型日期,获取当月日历
         *
         * @param value
         * @returns {string}
         */
        function datePanel()
        {
            var html = "<table width='100%' id='date_table'>";
            html += menuTable();
            html += addWeekTitle();
            html += mainTable();
            html += "</table>";
            return html;
        }

        /**
         * 获取日历
         *
         * @returns {string}
         */
        function mainTable()
        {
            var year = DEFAULT_DATE.getFullYear();
            var month = DEFAULT_DATE.getMonth();
            var day = DEFAULT_DATE.getDate();
            var week = DEFAULT_DATE.getDay();

            getDaysInMonth(year);
            var currentMonthMap = getMonthMap(year,month);

            return transArr2Table(currentMonthMap);
        }

        /**
         * 设定给定年份的每月天数
         *
         * @param year
         */
        function getDaysInMonth(year)
        {
            if(year%400 == 0 || (year%4 ==0 && year%100!=0))
            {
                DAYS_IN_SELECTED = DAYS_IN_SPECIAL;
            }
            else
            {
                DAYS_IN_SELECTED = DAYS_IN_NORMAL;
            }
        }

        /**
         * 当月日历数组,包括空白部分
         *
         * @param year
         * @param month
         * @returns {Array}
         */
        function getMonthMap(year,month)
        {
            var first_day_in_week = new Date(year,month,1).getDay();
            var last_day_in_week = new Date(year,month,DAYS_IN_SELECTED[month]).getDay();
            var daysInThisMonth = DAYS_IN_SELECTED[month];
            var mapDays = first_day_in_week + DAYS_IN_SELECTED[month] + 6 - last_day_in_week;

            var map = new Array(mapDays);
            var count = 1;
            for(var i=0;i<mapDays;i++)
            {
                if(i<first_day_in_week)
                {
                    map[i] = "  ";
                }
                else if(i<=daysInThisMonth+first_day_in_week-1)
                {
                    map[i] = ""+count;
                    count++;
                }
                else
                {
                    map[i] = "  ";
                }
            }
            return map;
        }

        /**
         * 将数组转换成html图标
         *
         * @param currentMonthMap
         * @returns {string}
         */
        function transArr2Table(currentMonthMap)
        {
            var html = "";
            var rows = currentMonthMap.length/7;
            for(var i=0;i<rows;i++)
            {
                html += "<tr>";
                for(var n=0;n<7;n++)
                {
                    var num = n+i*7;
                    if(currentMonthMap[num]=="  ")
                    {
                        html += "<td id='td_"+num+"'>"+currentMonthMap[num]+"</td>";
                    }
                    else if(currentMonthMap[num]==DEFAULT_DATE.getDate())
                    {
                        //点击时日期,高亮显示
                        html += "<td id='td_"+num+"' onclick=\"chooseDate(this);\" ";
                        html += "style='font-size: 13px;background-color: palegreen;text-align:center;'>"
                        html += currentMonthMap[num];
                        html += "</td>";
                    }
                    else
                    {
                        //其他日期,鼠标经过事件,点击事件
                        html += "<td id='td_"+num+"' onmouseover=\"changeColor('td_"+num+"')\" ";
                        html += "onmouseout=\"resetColor('td_"+num+"')\" ";
                        html += "onclick=\"chooseDate(this);\" ";
                        html += "style='font-size: 13px;text-align:center;'>";
                        html += currentMonthMap[num];
                        html += "</td>";
                    }
                }
                html += "</tr>";
            }
            return html;
        }

        /**
         * 日期选择菜单
         *
         * @returns {string}
         */
        function menuTable()
        {
            var html = "<tr>";
            html += "<td colspan='7'>";
            html += "<input style='width: 20px;font-size: 10px;' type='button'value='<<' onclick='change(-1,0);'/>";
            html += "<input style='width: 20px;font-size: 10px;' type='button'value='<' onclick='change(0,-1)'/>";
            html += "<input style='width: 30px;style='font-size:10px;'' type='text'value='"+DEFAULT_DATE.getFullYear()+"' id='year' onchange=\"textChange()\"/>";
            html += "<label style='font-size:10px;'>年</label>";
            html += "<input style='width: 15px;style='font-size:10px;'' type='text' value='"+(DEFAULT_DATE.getMonth()+1)+"' id='month' onchange=\"textChange()\"/>";
            html += "<label style='font-size:10px;'>月</label>";
            html += "<input style='width: 20px;font-size: 10px;' type='button'value='>'onclick='change(0,1)'/>";
            html += "<input style='width: 20px;font-size: 10px;' type='button'value='>>' onclick='change(1,0);'/></td>";
            html += "</tr>";
            return html;
        }

        /**
         * 星期表头
         *
         * @returns {string}
         */
        function addWeekTitle()
        {
            var html = "<tr>"
            for(var i=0;i<7;i++)
            {
                html += "<td style='font-size: 13px;text-align:center;font-weight: bold;'>"+WEEK[i]+"</td>";
            }
            html += "</tr>";
            return html;
        }

        /**
         * 鼠标经过变色事件
         * @param id
         */
        function changeColor(id)
        {
            document.getElementById(id).style.backgroundColor = "pink";
        }

        /**
         * 鼠标移除还原颜色
         *
         * @param id
         */
        function resetColor(id)
        {
            document.getElementById(id).style.backgroundColor = "";
        }

        /**
         * 手动修改年月栏位
         */
        function textChange()
        {
            var year = document.getElementById("year");
            var month = document.getElementById("month");

            updateDateTable(year.value,month.value);
        }

        /**
         * 点击修改年月
         *
         * @param yearChange
         * @param monthChange
         */
        function change(yearChange,monthChange)
        {
            var year = document.getElementById("year");
            var month = document.getElementById("month");
            year.value = parseInt(year.value) + yearChange;
            month.value =  parseInt(month.value)+ monthChange;

            updateDateTable(year.value,month.value);
        }

        /**
         * 更新日历
         *
         * @param year
         * @param month
         */
        function updateDateTable(year,month)
        {
            DEFAULT_DATE.setFullYear(parseInt(year));
            DEFAULT_DATE.setMonth(parseInt(month)-1);
            DEFAULT_DATE.setDate(DEFAULT_DATE.getDate());

            DATE_PANEL.innerHTML = datePanel();
        }

        /**
         * 选定日期
         *
         * @param td
         */
        function chooseDate(td)
        {
            var day = td.innerHTML;
            var year = document.getElementById("year").value;
            var month = document.getElementById("month").value;

            CONTAINER.value = year+SPLIT+month+SPLIT+day;
            DATE_PANEL.style.display = "none";
        }
    </script>
</head>
<body>
    <!--
        使用说明:
            div的id格式为 div_输入框的ID
            selectDate的第一个参数为输入框的ID,第二个参数为日期分隔符,必须输入

            已有校验:
                年份不做校验,负数为公元前
                月份为1-12
                日期为当月有效天数
    -->
    <input type="text" id="date1"/>
    <div id="div_date1" style="display:none;"></div>
    <input type="button" value="选择" onclick="selectDate('date1','-');"/>
</body>
</html>
时间: 2024-08-03 18:06:30

日历控件源码的相关文章

Android SwipeRefreshLayout下拉刷新控件源码简单分析

咱们在做Android APP开发的时候经常碰到有下拉刷新和上拉加载跟多的需求,这篇文章咱们先说说下来刷新,咱们就以google的原生的下拉刷新控件SwipeRefreshLayout来看看大概的实现过程. SwipeRefreshLayout是google自己推出的下拉刷新控件.使用起来也非常的简单,在满足条件的情况下下拉的时候会显示一个圆形的loading的动画效果,然后回调到上层,上层自己做刷新的一系列的处理,处理结束后调用SwipeRefreshLayout的setRefreshing(

开源日历控件DatePicker源码解析

在一些项目开发中,会使用日历去标识事务,所以根据美工出的效果图,我们可以采用不同的方法去实现.比如通过GridView扣扣你敢.自定义View实现日历控件,这些都是我们解决问题的手段,我也实现过一个自定义日历控件(Android自定义控件之日历控件55993)),由于我只是粗糙的进行实现,并没有进行过多的在控件的可扩展性上进行打磨设计,所以在本篇文章中,我秉着学习的态度分析下爱哥的鼎力巨作DatePicker-DatePicker. DatePicker开源项目地址:[https://githu

Android UI-自定义日历控件

Android UI-自定义日历控件 本篇博客笔者给大家分享一个日历控件,这里有个需求:要求显示当前月的日期,左右可以切换月份来查看日期. 我们想一想会如何去实现这样的一个控件,有开源的,但可能不太满足我们的特定的需求,这里笔者自定义了一个,读者可以根据自己的需求来修改代码.下面来说一下实现的思路: 首先我们要显示当前月份,自然我们要计算出当前的日期,并且把每一天对应到具体的星期,我们会有以下效果: 我们先想一下这样的效果用什么控件可以实现?很自然可以想到用网格视图GridView,但这里笔者使

javascript日历控件——纯javascript版

平时只有下班时间能code,闲来写了个纯javascript版.引用该calendar.js文件,然后给要设置成日历控件的input的id设置成calendar,该input就会变成日历控件. <!doctype html> <html> <head> <meta charset="utf-8"> <title>日历控件</title> <script src="js/calendar.js&quo

javascript日历控件

以前要用到日历控件都是直接从网上下载一套源码来使用,心里一直有个梗,就是想自己动手写一个日历控件,最近刚好来了兴趣,时间上也允许,于是自己摸索写了一个,功能还算完善,界面就凑合了.可能最值得说的一点就是让input控件内部右边显示一个按钮,我是直接给input加了个背景,然后把input的边框去掉实现的. 这个是最初版的,再往后打算做出纯javascript版的,再往后打算用JQuery做一套. <!doctype html> <html> <head> <met

Flex自定义组件开发之日周月日期选择日历控件

原文:Flex自定义组件开发之日周月日期选择日历控件 使用过DateField的我们都知道,DateField 控件是用于显示日期的文本字段,字段右侧带有日历图标.当用户在控件边框内的任一位置单击时,将弹出一个 DateChooser 控件,显示当月的所有日期.如果未选择日期,则该文本字段为空白,并且 DateChooser 控件中将显示当前日期的月份.当 DateChooser 控件处于打开状态时,用户可以在各个月份和年份之间滚动,并选择某个日期.选择日期后,DateChooser 控件关闭,

Android自定义View(CustomCalendar-定制日历控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/54020386 本文出自:[openXu的博客] 目录: 1分析 2自定义属性 3onMeasure 4onDraw 绘制月份 绘制星期 绘制日期及任务 5事件处理 源码下载 ??应项目需求,需要做一个日历控件,效果图如下: ???? ??接到需求后,没有立即查找是否有相关开源日历控件可用.系统日历控件是否能满足 ,第一反应就是这个控件该怎么画?谁叫咱自定义控件技术牛逼呢O(∩_∩)O哈哈~

Android自定义控件之日历控件

Android自定义控件之日历控件 2015-10-23 Android开发中文站 三月份学习android,至今也有半年有余,中间也做过两个项目,但是依然感觉自己做的应用不是很有新意,比不上应用市场上那些应用如此绚丽.所以自己仍需继续努力.学习至今,仍感觉自定义控件是一块硬骨头,还没修炼到身后的内功,下面就切入正题,以一次项目的需求,来实现一个自定义的日历控件.效果图先来一发. 我们分析下效果图,然后确定我们的需求. (1).绘制星期的自定义View,用于标识日期的礼拜. (2).绘制日期的自

自己用js写的两个日历控件

前一阵写了两个日历控件,做了简单的封装,发出来共朋友们参考. 第一个日历控件,条状的日历. (使用方法:调用initBarTime(id,evn),第一个参数是要渲染div的id,第二个参数是点击日期发生的事件) html思路分析:首先我们看出来这个日历分为两个部分第一部分是上面,整体的你去年月日日期的显示.第二部分是下面,具体某一天以及星期的日期显示.第三部分是下面两段的左右箭头,以及滚动功能. 上面年月日部分的日期我们用一个 p 标签来实现.下面则是用两组ul来实现,并且加入隐藏于用于记录每