javascript日历插件

原文:javascript日历插件

javascript日历插件

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

demo链接请点击我

基本的配置如下:

   targetCls
'',    输入框dom节点 默认为空 必填项
 beginyear 1978,     开始年份
 endyear  2050,    结束年份
 date  new Date(),  默认日期
 type  "yyyy-mm-dd" ,      日期格式(目前只支持这一种)
separator  '-' ,             日期链接符
wday  0 ,             周的第一天
language


{
year:"年",
month:"月",
monthList:["1","2","3","4","5","6","7","8","9","10","11","12"],
weekList:["日","一","二","三","四","五","六"]} // 默认为中文


方法如下:

 1. show():  显示日历面板。

 2. hide(): 隐藏日历面板。

 3. clear() 清除输入框的日期。

 4. getValue() 获取当前选中的日期。

 5. 提供callback回调。返回一个参数(每当点击一项时候 返回输入框的值 即:日历的值)。

所有的JS代码如下:

/**
 * javascript日历控件
 */

 function Calendar(options,callback){
    var self = this;
    self.options = $.extend({},defaults,options || {});
    self.targetCls = $(self.options.targetCls);
    if(self.targetCls.length < 1) {return;}
    self.language = self.options.language;
    self.flag = false;
    self.callback = callback;

    self._init();
    self._bindEnv();

 };
 $.extend(Calendar.prototype,{

    _init: function(){
        var self = this;
        // 先渲染日历面板
        self._renderCalendarPanel();
    },
    _renderCalendarPanel: function(){
        var self = this,
            options = self.options;
        // 如果input输入框有日期的话
        if(self.targetCls.val().length > 0) {
            self.date = self._dateParse(self.targetCls.val());
        }
        self.date = new Date(self.date);
        if(isNaN(self.date.getFullYear())){
            self.date = new Date();
        }
        var defYear = self.date.getFullYear(),
            defMonth = self.date.getMonth() + 1,
            defDay = self.date.getDate();

        // 定义每月的天数
        self.month_day = new Array(31,28+self._leapYear(defYear),31,30,31,30,31,31,30,31,30,31);

        // 定义每周的日期
        self.date_name_week = self.language.weekList;

        // 定义周末
        var saturday = 6 - options.wdays,
            sunday = (7-options.wdays >= 7) ? 0 : (7-options.wday);

        // 创建日历面板dom节点
        var date_pane = $('<div class="cxcalendar"></div>'),
            date_hd = $('<div class="date_hd"></div>').appendTo(date_pane),
            date_table = $('<table class="date_table"></table>').appendTo(date_pane);
        date_hd.html("<a class='date_pre' href='javascript://' rel='prev'>&lt;</a><a class='date_next' href='javascript://' rel='next'>&gt;</a>");

        var date_txt = $('<div class="date_txt"></div>').appendTo(date_hd),
            date_set = $('<div class="date_set"></div>').appendTo(date_hd),
            html = "";

        for(var i = options.beginyear; i < options.endyear; i++) {
            html +="<option value='"+i+"'>"+i+"</option>";
        }
        var year_list = $('<select class="year_set"></select>').html(html).appendTo(date_set).val(defYear);

        date_set.append(" - ");
        html = '';
        for(var i = 0; i < 12; i++) {
            html += '<option value="'+(i+1)+'">'+self.language.monthList[i]+'</option>';
        }
        var month_list = $('<select class="month_set"></select>').html(html).appendTo(date_set).val(defMonth);
        html = '<thead><tr>';
        // 遍历一周7天
        for(var i = 0; i < 7; i++) {
            html += "<th class='"
            // 周末高亮
            if(i == saturday) {
                html+= " sat";
            }else if(i == sunday) {
                html+= " sun";
            };
            html+="'>";
            html+= (i+options.wday * 1 < 7) ? self.date_name_week[i+options.wday] : self.date_name_week[i+options.wday - 7];
            html+="</th>";
        };
        html +="</tr></thead>";
        html +="<tbody></tbody>";
        date_table.html(html);

        // 面板及背景遮挡层插入到页面中
        date_pane.appendTo("body");

        // 创建遮罩层的目地是:只显示一个日历面板
        var block_bg=$("<div class='cxcalendar_lock'></div>").appendTo("body");

        // 赋值 全局
        self.dateTxt = date_txt;
        self.yearList = year_list;
        self.monthList = month_list;
        self.dateTable = date_table;
        self.saturday = saturday;
        self.sunday = sunday;
        self.datePane = date_pane;
        self.blockBg = block_bg;
        self.dateSet = date_set;
        self.defYear = defYear;
        self.defMonth = defMonth;

        // 根据年份 月份来渲染天
        self._renderBody(defYear,defMonth);
    },
    _dayNumOfMonth: function(Year,Month){
        var d = new Date(Year,Month,0);
        return d.getDate();
    },
    /*
     * 渲染日历天数
     * @param {y,m} 年 月
     */
    _renderBody: function(y,m){
        var self = this;
        var options = self.options;
        if(m < 1) {
            y--;
            m = 12;
        }else if(m > 12) {
            y++;
            m = 1;
        }
        var tempM = m,
            cur_m = m;

        m--;  // 月份从0开始的
        var prevMonth = tempM - 1,  //上个月的月份
            prevDay = self._dayNumOfMonth(y,tempM - 1), // 上个月的天数
            nextMonth = tempM + 1,   // 下个月的月份
            nextDay = self._dayNumOfMonth(y,tempM + 1),  //下个月的天数
            curDay = self._dayNumOfMonth(y,tempM);       // 当前月份的天数

        self.month_day[1]=28+self._leapYear(y);  //闰年的话 29天 否则 28天
        var temp_html = "",
            temp_date = new Date(y,m,1);
        var now_date = new Date();
        now_date.setHours(0);
        now_date.setMinutes(0);
        now_date.setSeconds(0);

        // 如果输入框有值的话
        if(self.targetCls.val().length > 0) {
            var val_date=self._dateParse(self.targetCls.val())
        }
        val_date=new Date(val_date);
        if(isNaN(val_date.getFullYear())){
            val_date=null;
        };
        // 获取当月的第一天
        var firstDay = temp_date.getDay() - options.wday < 0 ? temp_date.getDay() - options.wday + 7 : temp_date.getDay() - options.wday;
        // 每月所需要的行数
        var monthRows = Math.ceil((firstDay+self.month_day[m]) / 7);
        var td_num,
            day_num,
            diff_now,
            diff_set;
        var disabled;
        for(var i= 0; i < monthRows; i++) {
            temp_html += "<tr>";
            for(var j = 0; j < 7; j++) {
                td_num=i*7+j;
                day_num=td_num-firstDay+1;
                if(day_num<=0) {
                    if(day_num == 0) {
                        day_num = prevDay - day_num
                        text_m = prevMonth
                    }else {
                        day_num = prevDay + day_num;
                        text_m = prevMonth
                    }

                }else if(day_num > self.month_day[m]){
                    day_num = day_num - curDay;
                    text_m = nextMonth
                }else {
                    text_m     = cur_m;
                }
                temp_html+="<td";
                if(typeof(day_num) == 'number') {
                    diff_now=null;
                    diff_set=null;
                    temp_date = new Date(y,m,day_num);

                    if(text_m == cur_m) {
                        diff_now=Date.parse(now_date)-Date.parse(temp_date);
                        diff_set=Date.parse(val_date)-Date.parse(temp_date);
                    }
                    if(cur_m > text_m || cur_m < text_m) {
                        disabled = 'disabled';
                    }else {
                        disabled = "";
                    }
                    temp_html+=(" title='"+y+options.separator+tempM+options.separator+day_num+"' class='num "+disabled+"");

                    // 高亮周末、今天、选中
                    if(diff_set==0){    //选中的时候 增加select 类名
                        temp_html+=" selected";
                    }else if(diff_now==0){
                        temp_html+=" now";   // 当前时间增加now类名
                    }else if(j==self.saturday){
                        temp_html+=" sat";   // 周六增加sat类名
                    }else if(j==self.sunday){
                        temp_html+=" sun";   // 周日增加sun类名
                    };
                    temp_html+=("'");
                };
                temp_html+=(" data-day='"+day_num+"'>"+day_num+"</td>");
            }
            temp_html+="</tr>";
        }
        $(self.dateTable).find("tbody").html(temp_html);
        $(self.dateTxt).html("<span class='y'>"+y+"</span>"+options.language.year+"<span class='m'>"+options.language.monthList[m]+"</span>"+options.language.month);
        $(self.yearList).val(y);
        $(self.monthList).val(m+1);

        return this;
    },
    _dateParse: function(date){
        var newdate = date;
        newdate=newdate.replace(/\./g,"/");
        newdate=newdate.replace(/-/g,"/");
        newdate=newdate.replace(/\//g,"/");
        newdate=Date.parse(newdate);
        return newdate;
    },
    /*
     * 判断是否是闰年
     * @param y 年份
     * 1.能被4整除且不能被100整除 2.能被100整除且能被400整除
     */
    _leapYear: function(y) {
        return ((y%4==0 && y%100!=0) || y%400==0) ? 1 : 0;
    },
    _bindEnv: function(){
        var self = this;
        $(self.targetCls).unbind('click').bind('click',function(){
            self.show();
        });

        // 关闭面板事件
        self.blockBg.unbind('click').bind("click",function(){
            self.hide();
        });

        // 点击上一页 下一页事件
        self.datePane.delegate('a','click',function(){
            if(!this.rel){return};
            var _rel = this.rel;
            if(_rel == 'prev') {
                self._renderBody(self.yearList.val(),parseInt(self.monthList.val(),10) -1);
                return;
            }else if(_rel == 'next') {
                self._renderBody(self.yearList.val(),parseInt(self.monthList.val(),10) +1);
                return;
            }
        });

        // 选择日期事件
        self.datePane.delegate('td','click',function(){
            var _this = $(this);
            if(_this.hasClass('num') && !_this.hasClass('disabled')) {
                self.dateTable.find("td").removeClass("selected");
                _this.addClass("selected");
                var day = _this.attr("data-day");
                self._selectDay(day);
            }
        });

        // 显示年月选择
        self.dateTxt.unbind('click').bind("click",function(){
            self.dateTxt.hide();
            self.dateSet.show();
        });

        //更改年月事件
        self.yearList.unbind('change').bind("change",function(){
            self._renderBody(self.yearList.val(),self.monthList.val());
        });
        self.monthList.unbind('change').bind("change",function(){
            self._renderBody(self.yearList.val(),self.monthList.val());
        });
    },
    /*
     * 选择某一天的时候 把值存入输入框里 且面板隐藏
     * @_selectDay {private}
     */
    _selectDay: function(d) {
        var self = this;
        var year,
            month;
        month = self.monthList.val();
        day = d;
        var options = self.options;
        if(options.type == 'yyyy-mm-dd') {
            month="0" + self.monthList.val();
            day= "0" + d;
            month=month.substr((month.length-2),month.length);
            day=day.substr((day.length-2),day.length);
        }
        self.targetCls.val(self.yearList.val()+options.separator+month+options.separator+day);
        self.hide();

        self.callback && $.isFunction(self.callback) && self.callback(self.yearList.val()+options.separator+month+options.separator+day);
        return this;
    },
    /*
     * 显示日历面板
     * @method  show {public}
     */
    show: function(){
        var self = this;
        if(self.flag) {
            return;
        }
        var doc_w = document.body.clientWidth,
            doc_h = document.body.clientHeight,
            pane_top = self.targetCls.offset().top,
            pane_left = self.targetCls.offset().left,
            obj_w = self.targetCls.outerWidth(),
            obj_h = self.targetCls.outerHeight();
        pane_top= pane_top+obj_h;
        self.datePane.css({"top":pane_top,"left":pane_left}).show();
        self.blockBg.css({width:doc_w,height:doc_h}).show();
        self.flag = true;
        return this;
    },
    /*
     * 清除日期
     * @method clear {public}
     */
    clear: function(){
        var self = this;
        self.targetCls.val('');
        self._renderBody(self.defYear,self.defMonth);
        self.hide();
        return this;
    },
    /*
     * 获取当前选中的日期
     * @method getValue {public}
     * @return val
     */
     getValue: function(){
        var self = this;
        return self.targetCls.val();
     },
    /*
     * 隐藏日历面板
     */
    hide: function(){
        var self = this;
        if(!self.flag) {return;}
        self.datePane.hide();
        self.blockBg.hide();
        self.dateSet.hide();
        self.dateTxt.show();
        self.flag = false;
        return this;
    }
 });

 var defaults = {
    targetCls        :        '',             //渲染日历的class
    beginyear        :        1978,           //开始年份
    endyear          :        2050,           //结束年份
    date             :        new Date(),     // 默认日期
    type             :        "yyyy-mm-dd",      // 日期格式
    separator        :        "-",              // 日期链接符
    wday             :        0,              // 周第一天
    language         :       {
                                year:"年",
                                month:"月",
                                monthList:["1","2","3","4","5","6","7","8","9","10","11","12"],
                                weekList:["日","一","二","三","四","五","六"]}
 };

代码没有什么好解释的 相应的有注释,可以看看源码 不难的。

HTML代码可以这样写:

我是时间控件1:<input name="mydate" type="text" class="input_cxcalendar" readonly style="width:200px;">

初始化代码如下:

$('.input_cxcalendar').each(function(){
    var a = new Calendar({
        targetCls: $(this)
    },function(val){
        console.log(val);
    });
});

日历控件demo下载

时间: 2024-10-19 22:43:13

javascript日历插件的相关文章

JavaScript日历控件插件使用详解(支持中文英文繁体)

kimsoft-jscalendar一款优秀的#JavaScript#日历控件,kimsoft-jscalendar.它小巧,单文件:支持多语言:兼容ie6.0+, firefox1.0+, Opera9,其它浏览器未测试:回显选定的时间:Apache license 2.0,商业友好.用 iframe 解决 IE 中层在 select 控件上显示的问题 一.什么是 kimsoft-jscalendar 一个简洁的avaScript日历控件,可在Java Web项目,.NET Web 项目中使用

给开发者准备的 10 款最好的 jQuery 日历插件

这篇文章介绍的是 10 款最棒而且又很有用的 jQuery 日历插件,允许开发者们把这些漂亮的日历插件结合到自己的网站中.这些日历插件易用性都很强,轻轻松松的就可以把漂亮的日历插件装饰到你的网站了.希望下 面的插件列表能给予你一定的帮助,让你的 web 开发更快更好.旧版本的日历插件和下拉框已经被淘汰啦,好好欣赏 jQuery 日历插件给你带来的强烈视觉冲击吧! CLNDR.js CLNDR.js 是一个日历插件,用来创建日历,允许用户随意的按照自己的想法去自定义日历.这个插件不会生成任何的标记

Wijmo 日历插件

原文 http://www.cnblogs.com/huruda/p/3145098.html 说明: 因为项目(OA)的需要,我负责开发日程的模块,相信大家用过谷歌的日历了吧,是不是觉得挺好用,但又苦于无法实现? 这里告诉你一个很好的插件,Wijmo,而里面有一个类似谷歌的日历事件插件,真的很好很强大,注意,我不是托. 当时找到这个插件的时候,真心佩服那些牛逼的外国开发员,能做到这么厉害,并且还开源了. 因为菜鸟,苦苦做了一个多星期才完成,个中原因能归结为: 1.没有中文的介绍和帮助,百度谷歌

jQuery日历插件datepicker用法详解_jquery

 jQuery是一款不可多得的非常优秀的javascript脚本开发库,而基于其上的很多插件也是非常规范和卓越的,如果错过这番美景真是太可惜了,比如datepicker这个插件. 一般MIS系统的前端,尤其是用户注册页面,都会有诸如"出身年月"的日期输入框,最简单的做法就是使用一个<input type="text"/>标签,这样做的弊端有很多:首先是与数据库字段类型的匹配.其次是输入日期的合法性如"13月"或者闰年等等问题,如果深入

jquery日历插件datepicker用法分析_jquery

本文实例讲述了jquery日历插件datepicker用法.分享给大家供大家参考,具体如下: 我用过好几种日历插件,有的太花哨,有的太简单,有的浏览器不兼容等等,没有一个能让我感到满意的,后来同事给我推荐了jquery.datepick这个插件,我从官方网站下了一个,亲自做了一下,感觉相当的不错,逻辑和样式可以完全分开,并且非常的灵活,支持30个国家的语言,基本能满足我的要求. 这里给出本站下载地址:http://www.jb51.net/jiaoben/19622.html 解压jquery.

bootstrap日历插件datetimepicker使用方法_javascript技巧

如何使用bootstrap日历datetimepicker插件? 一.引入文件 1.css样式 <link href="/css/bootstrap-datetimepicker.min.css" rel="stylesheet" media="screen"> 2.js文件 <script type="text/javascript" src="/js/bootstrap-datetimepick

为开发者准备的10款最好的jQuery日历插件_jquery

这篇文章介绍的是 10 款最棒而且又很有用的 jQuery 日历插件,允许开发者们把这些漂亮的日历插件结合到自己的网站中.这些日历插件易用性都很强,轻轻松松的就可以把漂亮的日历插件装饰到你的网站了.希望下面的插件列表能给予你一定的帮助,让你的 web开发更快更好.旧版本的日历插件和下拉框已经被淘汰啦,好好欣赏 jQuery 日历插件给你带来的强烈视觉冲击吧! 1. CLNDR.js CLNDR.js 是一个日历插件,用来创建日历,允许用户随意的按照自己的想法去自定义日历.这个插件不会生成任何的标

jquery日历插件e-calendar升级版_jquery

jQuery事件日历插件e-calendar,支持针对指定日期自定义日程安排(无条数限制),设置过日程的日期会高亮显示,兼容IE7+主流浏览器. 原版使用方法及演示地址:e-calendar原版 (鼠标移动到天显示当天的日程安排) 升级版介绍: 1.同一天可存在多个事件交集 2.点击天在日历下方出现日程列表 3.点击日程列表可添加其事件 . 4.添加item-grid的显示和隐藏 5.Events中数组集合可添加id,type等元素(区分日程类型:任务类型或日程类型) 6.增加年份选择,月份选择

基于jquery 日历插件应用

1)jQuery Frontier Calendar是一个可灵活定制的月日历jQuery插件,看起来类似于Google Calendar.当在一个日期单元格中有比较多的待办事项 时,将出现一个更多的链接,点击这个链接会弹一个jQuery模式对话框来显示所有的事务.这个日历还支持通过CSS文件改变整个日历的背景. 主页: http://code.google.com/p/jquery-frontier-calendar/            2)NoGray 制定了一个像我们这样的Web开发人员