• 日历插件的详解


    本插件是在jQuery 1.6.1基础上进行开发的。

    var _count = 0;

    var _expando = "CCalendar-" + (+new Date()) + "-",       

    var CCalendar = function(element,options){

      this.initialize.apply(this,arguments);     //在new出来的CCalendar对象的执行上下文中执行initialize方法,并传入参数element,options。

      _count++;              //这里的arguments是[element,options],通过apply方法后,会把数组中的每一项传参给initialize,而不是传数组给它。

    }

    //默认配置
    CCalendar.defcfg = {
      id: null,
      showCount: 1,
      direction: "Right",
      startDate: new Date(),
      maxDate: false,
      minDate: false,
      lang: 'zh-cn',

      onSelect: null,
      onSelectBack: null,
      onHide: null,
     
    };

    CCalendar.prototype = {

      constructor: CCalendar,  

      initialize: function (element, options) {
        options = options || {};               //如果没有传入对象,就使用空对象
        this.element = $(element);          //把元素转化成jQuery对象
        this.format = GLOBLE.parseFormat(options.format || this.element.data('date-format') || 'yyyy-mm-dd');

          //GLOBLE.parseFormat解析日期的格式,优先级:开发人员传入的格式->元素date-format属性的格式->默认格式'yyyy-mm-dd'
        this.isInput = this.element.is("input");         

        // 合并默认配置
        var dftCfg = CCalendar.defcfg;
        for (var i in dftCfg) {
          if (options[i] === undefined) {   //如果是传入的参数,就不使用默认值
            options[i] = dftCfg[i];
          }
        }

        this.direction = options.direction; //默认提示控件在Right
        options.id = options.id || _expando + _count;     //id为CCalendar-当前日期的毫秒数-当前的_count
        this.picker = $("<div/>", {"id": options.id, "class": "ui-date"}).appendTo('body').bind({
          click: $.proxy(this.click, this)    //$.proxy返回一个新函数,并且这个新函数始终保持了特定的上下文(这里就是this,也就是new出来的CCalendar)
        });      //对这个div,也就是this.picker绑定click事件

         //$.proxy( me.test, me, you, they ),test(you,they,event)。第一个参数为function(点击事件触发的函数),第二个参数为context(函数执行的上下文),第三个参数,以及后面的参数,都会传入到function中去。function中总会有一个event参数。event.type -> click。

        this.create(options);
        //如果是输入框
        if (this.isInput) {
          this.element.bind({
            focus: $.proxy(this.show, this),          //对传入的input元素绑定focus和keyup事件
           
          });
        }

        else {         //如果元素不是input,就对元素绑定click事件

          this.element.bind('click', $.proxy(this.show, this));
        }

      }, 

      //创建日历
      create: function (options) {
        this.setOptions(options);
        this.fill(this.date);
      }, 

      setOptions: function (options) {
        this.options = options;
        this.options.startDate  && (this.options.startDate = GLOBLE.parseDate(this.options.startDate, this.format));    

        //是否传入了日历中显示的选中日期,如果没有就是当前时间的日期,如果有,传入的显示日期必须可以转化成相应的日期格式。默认为:'yyyy-mm-dd'
        this.lang =GLOBLE.lang[this.options.lang];       //默认为'zh-cn'
        (this.options.maxDate && (this.options.maxDate = GLOBLE.parseDate(this.options.maxDate, this.format)));
        (this.options.minDate && (this.options.minDate = GLOBLE.parseDate(this.options.minDate, this.format)));

          //日历控件里面可以选择的日期最大值和最小值,传入的日期必须能够转换成相应的日期格式,默认为:'yyyy-mm-dd'
        this.date = {      //日历上选中的日期,如果没传入startDate参数,那么就是当前时间的日期
          year: this.options.startDate.getFullYear(),
          month: this.options.startDate.getMonth(),
          days: this.options.startDate.getDate()
        };
      }, 

        //构建主体
      fill: function (date) {         //日历上默认被选择的日期
        var dp = this,
        options = dp.options;

        var disabled,
        isShowToday = true,
        year = (date.year || this.date.year),     //其实这里的date和this.date是同一个
        month = (date.month || this.date.month),
        _today = new Date(GLOBLE.today.year, GLOBLE.today.month, GLOBLE.today.date);

          //比如在中国大陆、、香港、新加坡、马来西亚、菲律宾等地区的本地时间比UTC快8小时,记作UTC+8,意思就是比UTC时间快8小时。   

        this.date.year = year,
        this.date.month = month;

        var main = this.dom ? this.dom.main : $("<div/>", {"class": "main"}).appendTo(this.picker);  

          //再新建一个div,添加到id为options.id的div中。我们这里把外层的div叫做div1,main的称作div2。
        main.empty();       //移除元素的所有内容,包括所有文本和子节点。remove,连元素都移除
        for (var i = 0; i < options.showCount; i++) {    //默认情况下为1

          var dayCount = GLOBLE.getDaysInMonth(year, month),  

              //得到当前被选择日期的当前月的天数。(假设今天是2014,3月5号,那么year=2014,month=2)
            prev = GLOBLE.getPNDate(year, (month + 1), -1),    //得到上一个月的日期,{year:2014,month:1,day:28}
            next = GLOBLE.getPNDate(year, (month + 1), 1),    //得到下一个月的日期,{year:2014,month:3,day:30}
            startPad = new Date(year, month, 1).getDay(),

               //得到当前被选择日期的当前月的第一天是星期几,返回值是 0(周日) 到 6(周六) 之间的一个整数。{2014.3.1号是星期六}
            pday,
            list = $("<div/>", {  "class": "ui-date-list ui-month" + i + (options.showCount > 1 && year == GLOBLE.today.year &&

              month == (GLOBLE.today.month + 1) ? 'ui-month-cur' : "")  });  //新建一个div,我们称为div3

          var html = ['<div class="ui-date-head ui-date-top">'];
          (i == 0) && html.push('<a data-action="YEAR_LEFT" class="ui-year-left" href="javascript:void(0)" title="'

              + dp.lang.previousYear + '">&laquo;</a><a data-action="MONTH_LEFT" class="ui-month-left" href="javascript:void(0)" title="'

              + dp.lang.previousMonth + '">&lsaquo;</a>');

                //添加上一年,上一个月的链接,只有i==0时才添加,因为一个日历上只需要一个。
          html.push('<a data-action="SELECT_YEAR" class="ui-year" href="javascript:void(0)" title="' +

              dp.lang.selectYear + '">' + year + '</a>年<a data-action="SELECT_MONTH" class="ui-month" data-year="' + year + '"

              href="javascript:void(0)" data-dom="month" title="' + dp.lang.selectMonth + '" >' +

              (((month + 1) < 10 ? '0' : '') + (month + 1)) + '</a>月');         //如果月份少于10,就添加0,变成09,08这种。{03}
          (i + 1 == options.showCount) && html.push('<a data-action="MONTH_RIGHT" class="ui-month-right" href="javascript:void(0)" title="' +           dp.lang.nextMonth + '">&rsaquo;</a><a data-action="YEAR_RIGHT" class="ui-year-right" href="javascript:void(0)" title="' +           dp.lang.nextYear + '">&raquo;</a>');

                //添加下一月,下一年的链接,也只添加一次。

          html.push('</div><div class="ui-date-content clearfix"><div class="ui-date-week">');
          for (var j = 0; j < 7; j++){

              html.push('<span class="ui-week ' + j + '">' + dp.lang.week[j] + '</span>');     //添加星期一到星期天

          }

          html.push('</div><div class="ui-date-days">');
          var nday = startPad = startPad == 0 ? 6 : startPad - 1;     //假设今天星期六,那么返回6,startPad 和nday等于5.
          for (; startPad >= 0; startPad--) {  //循环6次
               pday = (prev.day - startPad)  //第一次循环时,prev.day=28,startPad =5,pday=23
               _innerDay(prev, pday, true);  //此方法就是把前一个月的23号显示在日历插件上,再循环就是24,25,一直到28号。它的显示样式是隐式的
          }

          for (var j = 1; j <= dayCount; j++) {       //31天,2014年3月
              disabled = false;
              var day = new Date(year, month, j).getDay();   //针对每天,得到是星期几
              html.push('<div class="d-' + day);

              if (options.maxDate && options.maxDate <= new Date(year, month, j) ||     //默认maxDate 为null

                options.minDate && options.minDate >= new Date(year,month, j)) {
                  disabled = true;
                  html.push(' ui-days-disabled');
              }

              if (GLOBLE.today.year == year && GLOBLE.today.month == month && GLOBLE.today.date == j) {
                  html.push(' ui-days-current');         //如果是当天的日期,比如3月5号,也就是j=5时,就让它的class变成current。
                  if (disabled) isShowToday = false;
              }
              html.push('"><a data-action="DAY" href="javascript:void(0)" data-year="' + year + '" data-month="' + (month + 1 ) +

                '" data-day="' + j + '" data-disabled="' + disabled + '" data-old="' + (new Date(year, month, j) < _today ? 1 : 0 ) +

                  '" >' + j + '</a></div>');

          }
          for (var j = 1; j < 42 - dayCount - nday; j++) {     //42-31-5 = 6,循环5次,因为日历上总共要显示42天
              _innerDay(next, j);        //把下个月的几天显示在日历上,隐式显示。
          }
          html.push('</div></div>');
          list.html(html.join(""));        //把所有的元素添加到list(div3)
          main.append(list);          //再把div3添加到div2中,div2在div1中,div1在body中。
          if (++month == 12) {          //month=2,这时month=3
              year++;
              month = 0;
          }
        }

          if (GLOBLE.ie) {  //如果是ie
            this.picker.width(200 * options.showCount);      //把div1宽度设置为(200*1=200)
            if (GLOBLE.ie == 6) {    //如果是ie6
              var background = $('<div />', {"class": "ui-date-mark"}).css(  //新建一个div称为div4,把宽度和高度设置为div1的宽度和高度

                {
                   this.picker.innerWidth(),
                  height: this.picker.innerHeight()
                }

              ).html('<iframe frameborder="0" src="about:blank" scrolling="no"></iframe>'); //并在div4中装入一个iframe
              this.picker.append(background);  //把div4添加到div1中。这时的html结构就是

                //<div1><div2>日历控件的元素</div2><div4><iframe></iframe></div4></div1>,iframe做垫片,IE6的bug
            }
        }
        this.dom = {      

            //在this上新添加dom属性,等于{},对象里面有一个main属性就是div2,通过对象的属性来引用(div2中有日历控件需要的html标签)。当重新调用fill时,只需要取到div2,并且empty,就可以重新往div2添加元素了(生成新的日历控件内容)

            main: main
        };

        function _innerDay(obj, pday, flag) {
            html.push('<div class="d-' + pday);
            if (options.maxDate && options.maxDate <= new Date(obj.year, obj.month, pday) ||

              options.minDate && options.minDate >= new Date(obj.year, obj.month, pday)) {
                disabled = true;
                html.push(' ui-days-disabled');
            }

            html.push(' ui-days-other">');
            html.push('<a data-action="DAY" href="javascript:void(0)" data-year="' + obj.year + '" data-disabled="' + disabled +

              '" data-month="' + (obj.month + 1 ) + '" data-day="' + pday + '">' + pday + '</a>');
            html.push('</div>');
        }
      },   

      //显示
      show: function (e) {
        

        this.offset();   //设置日历控件显示的位置

        this.picker.show();
        $(window).bind('resize', $.proxy(this.offset, this));     //窗口改变,就会重新计算日历控件的位置。
        if (e) {
          e.stopPropagation();     //已经被 jQuery 做过标准化处理
          e.preventDefault();
        }

        var that = this;
        $(document).one('mousedown', function (ev) {       //当用户点击页面的其他地方时(不是日历控件)就会隐藏日历控件。one方法表明只执行一次回调方法
          if ($(ev.target).closest('.ui-date').length == 0) {  

          //closest方法,从当前元素开始,沿 DOM 树向上遍历,直到找到已应用选择器的一个匹配为止。 返回包含零个或一个元素的 jQuery 对象。由于只有this.packer有.ui-date属性,因此只有点击了this.packer才会有元素,等于0就代表点击的不是页面上的日历控件,因此隐藏

            that.hide();
          }
        });

      },

      offset: function () {

        //jQuery中的.height()、.innerHeight()和.outerHeight(),height就是content的高度,innerHeight是高度+padding,outerHeight是高度+padding+border+(如果传入true,则加上margin,如果传入false或者不传,就不加)

        this.height = this.element.outerHeight();    
        this.width = this.element.outerWidth();
        var offset = this.element.offset();//返回元素的偏移坐标。该方法返回的对象包含两个整型属性:top 和 left,以像素计。此方法只对可见元素有效。

        var top = offset.top,
        left = offset.left,
        ww = $(window).width(),
        pw = this.picker.width();

        var css = { top: top + this.height };  

        //元素偏移页面的高度+元素的高度(不包括margin),这时日历控件就可以显示在元素的下面了(刚好在元素的border下)。
        switch (this.direction) {      //默认为Right
          case "Left":
            css.left = left >= pw ? (left - pw ) + this.width : left
            break;
          case "Right":   //日历控件的left等于元素的left,左对齐显示。如果超过了窗口的宽度,就让日历控件跟元素右对齐
            css.left = ww <= (pw + left) ? left - pw + this.width : left
            break;
        }

        this.picker.css(css);
      },

      //隐藏
      hide: function () {
        this.picker.hide();    //日历控件隐藏

        typeof this.options.onHide == "function" && this.options.onHide.call(this);  
      },  

    //监听点击事件,点击日历时,触发
      click: function (e) {
        e.stopPropagation();
        e.preventDefault();
        var dp = this,
        options = dp.options,
        target = $(e.target).closest('a')[0];    

          //看用户点击的是哪个链接元素,针对不同的链接元素进行不同处理,因此在创建日历控件的时候,只要是a链接的都会响应click事件
        if (!target) return false;          //如果点击的是日历控件上的其他位置,没有a链接的,将不做任何处理
        if (target.getAttribute('data-disabled') == "true") return false;  

          //如果是禁止的选项,比如,定义了最大日期和最小日期,那其他范围的日期,点击也不做任何处理
        var action = target.getAttribute('data-action');   //除了有a链接,还必须保证a链接上有data-action属性,此插件就是通过data-action来调用不同的回调方法。
        if (!action) return false;

        switch (action) {
          case "SELECT_YEAR":    //点击日历控件上的年份时,会弹出一个近10年的选择框,用户可以针对这个选择框点击上一页(上一个10年)和下一页|(下一个十年)
            {
              dp.createYearModel(dp.date.year, target);
            }
            break;
          case "PREV-10-YEAR":      //如果点击年份选择框中的上十年或者下十年,就重新生成新的十年选择框
          case "NEXT-10-YEAR":
            {
              dp.createYearModel(parseInt(target.getAttribute("data-year")), null);
            }
            break;
          case "SELECT_MONTH":     //点击月份,就会弹出一个12个选项(从1到12)的月份选择框
            {
              dp.createMonthModel(dp.date.month, target);    //实现方案跟年份的差不多,没年份的复杂,因为月份没有上十月和下十月,只有12个月
            }
            break;
          case "YEAR":        //当点击年份选择框中的年份时,就触发
            {
              dp.fill({
                year: parseInt(target.getAttribute("data-year"))       //重新生成新的日期时间
              });
            }
            break;
          case "MONTH":
            {
              dp.fill({
                month: parseInt(target.getAttribute("data-month") - 1)       //重新生成新的日期时间
              });
            }
            break;
          case "DAY":
            {
              this.select(target);      //选择日时,就会选择这个日期
            }
            break;
          case "YEAR_LEFT":         //日历控件还有上一年的按钮
            {
              dp.date.year -= options.showCount;        //年份减少一年,showCount默认为1
              dp.fill(dp.date);     //重新生成日期
            }
            break;
          case "YEAR_RIGHT":           //以此类推
            {
              dp.date.year += options.showCount;     
              dp.fill(dp.date);
            }
            break;
          case "MONTH_LEFT":            //以此类推
            {
              dp.date.month -= options.showCount;
              if (dp.date.month < 0) {
                dp.date.month = dp.date.month + 12;
                dp.date.year--;
              }
              dp.fill(dp.date);
            }
            break;
          case "MONTH_RIGHT":     //以此类推
            {
              dp.date.month += options.showCount;
              if (dp.date.month > 11) {
                dp.date.month = dp.date.month - 12;
                dp.date.year++;
              }
              dp.fill(dp.date);
            }
            break;
          default :
              {
              }
        }
      }, 

      select: function (target) {
        var dp = this,
        options = dp.options;

        var yyyy = target.getAttribute('data-year'),     //得到当前的年份
          yy = yyyy.substr(2),
          m = parseInt(target.getAttribute('data-month')),      //得到当前的月份
          mm = m < 10 ? '0' + m : m,      //格式化为两位的月份
          d = parseInt(target.getAttribute('data-day')),    //得到当前的天
          dd = d < 10 ? '0' + d : d,     //格式化天为两位数
          date = new Date(yyyy, m - 1, d),     
          time = date.getTime(),
          back = GLOBLE.formatDate(date, dp.format),    //把当前选择的日期格式化
          backData = {      //传给回调方法的json对象,使之可以使用各种格式的日期数据
            yyyy: yyyy,
            yy: yy,
            mm: mm,
            m: m,
            dd: dd,
            d: d,
            back: back,
            date: date,
            time: time
          };

        //选择日期前
        if (this.options.onSelect && !this.options.onSelect.call(dp, backData))     //如果传入onSelect调用后,传入选择的日期,返回false,则不做任何处理

          return null;   //这里可以让开发人员传入对象时,写上onSelect方法,然后在方法里面,判断选择的日期是否可选
        if (!dp.isInput) {
            
            dp.element.find('input').prop('value', back);    //如果元素不是input,就去找input,然后显示出来
           
            dp.element.data('date', back);
        }

        else {
            dp.element.prop('value', back);    //把日期显示在input框中
         }

        //选择日期后
        if (!this.options.onSelectBack || ( this.options.onSelectBack && this.options.onSelectBack.call(dp, backData) === true)) {

          //如果传入onSelectBack方法,那么选择日期,并显示在input后,如果 onSelectBack方法根据选择的日期返回true,就隐藏,如果返回false,就不隐藏日历,让用户继续选择。
          dp.hide();    //隐藏日历控件
        }
      },

      //创建月份面板
      createMonthModel: function (month, target) {
        var self = this,
        list = $(".ui-month-list", self.dom.main);

        if (list.length == 0) {
          list = $("<div/>", {"class": "ui-month-list"});
          self.dom.main.append(list);
          self.dom["month"] = list;
          self.dom.main.bind("mousedown", function (ev) {
            if ($(ev.target).closest('.ui-month-list').length == 0) {
              list.hide();
            }
            return false;
          });
        }

        if (target) {
          var offset = $(target).position();
          list.css({
            top: offset.top + 26,
            left: offset.left - 23 / 2
          }).show();
        }

        var items = [];

        for (var i = 1; i <= 12; i++) {
          items.push({
            value: i,
            label: i,
            role: 'MONTH'
          });
        }

        var current = {
          value: month,
          label: month
        };
        var html = [];
        for (var j = 0, l = items.length; j < l; j++) {
          var m = items[j]
          html.push('<a href="javascript:void(0)" data-action="' + m.role + '" class="' + (m.value < GLOBLE.today.month + 1 ? " ui-date-old" : "") + (m.value == GLOBLE.today.month + 1 ? " ui-date-current" : "") + '" data-month="' + m.value + '">' + m.label + '</a>');

        }
        list.html(html.join(""));
      },

      //创建年份面板
      createYearModel: function (year, target) {     //传入的是当前的年份,也就是2014,
        var self = this,
        years = $(".ui-year-list", self.dom.main);

        if (years.length == 0) {
          years = $("<div/>", {"class": "ui-year-list"});   //如果没有显示年份的选择框,就新建一个div,表示year
          self.dom.main.append(years);
          self.dom["year"] = years;
          self.dom.main.bind("mousedown", function (ev) {
            if ($(ev.target).closest('.ui-year-list').length == 0) {
              years.hide();
            }
            return false;
          });
        }

        if (target) {        //把这个年份的选择框,定位到日历年份的位置
          var offset = $(target).position();
          years.css({
            top: offset.top + 17,
            left: offset.left - 37 / 2
          }).show();
        }

        var items = [     //item数组的第一项是上十年的按钮
        {
          value: year - 10,
          label: '&laquo;',
          role: 'PREV-10-YEAR'
        }
        ];

        for (var i = year - 6; i < year + 4; i++) {     //前6年,当前年份,后3年

          items.push({
            value: i,
            label: i,
            role: 'YEAR'
          });
        }
        items[7] = {value: year, label: year, role: 'YEAR', current: true};
        items.push({       ////item数组的最后一项是下十年的按钮
          value: year + 10,
          label: '&raquo;',
          role: 'NEXT-10-YEAR'
        });

        var current = {    //当前年份,也就是2014
          value: year,
          label: year
        };
        var html = [];
        for (var j = 0, l = items.length; j < l; j++) {   //针对items数组,创建这个年份的选择框
          var y = items[j]
          html.push('<a href="javascript:void(0)" data-action="' + y.role + '" class="' + (y.value < GLOBLE.today.year ? " ui-date-old" : "") + (y.value ==       GLOBLE.today.year ? " ui-date-current" : "") + '" data-year="' + y.value + '">' + y.label + '</a>');

        }
        years.html(html.join(""));
      },

        

    }

    var GLOBLE = {
      ie: document.all && navigator.userAgent.match(/s{1}d{1}/),
      //语言包
      lang: {
        "zh-cn": {
          week: ['日', '一', '二', '三', '四', '五', '六'],
          previousMonth: '上一月',
          nextMonth: '下一月',
          previousYear: '上一年',
          nextYear: '下一年',
          selectYear: '选择年',
          selectMonth: '选择月',
          more: '更多',
          today: '今'
        },

        "en":{

            .....    //英文,国际化

        }
      },
        //今天
      today: {
        year: new Date().getFullYear(),
        month: new Date().getMonth(),
        date: new Date().getDate()
      },
        //是否是闰年
      isLeapYear: function (year) {
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
      },
      //获取月份的天数
      getDaysInMonth: function (year, month) {
        return [31, (GLOBLE.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
      },
        //获取上下月
      getPNDate: function (year, month, path) {
        if ((month += (path || 0)) < 1) {
          month = 12;
          year--;
        }

        else if (month > 12) {
          month = 1;
          year++;
        }
        var date = new Date(year, month, 0);
        return {
          year: date.getFullYear(),
          month: date.getMonth(),
          day: date.getDate()
        };
      },
        //转换为格式对象
      parseFormat: function (format) {
        var separator = format.match(/[./-s].*?/), parts = format.split(/W+/);
        if (!separator || !parts || parts.length === 0) {
          throw new Error("Invalid date format.");
         }
        return {
          separator: separator,
          parts: parts
        };
      },
      //按照格式对象,格式化字符日期
      parseDate: function (date, format) {
        var parts = date.split(format.separator), date = new Date(), val;
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        date.setMilliseconds(0);
        if (parts.length === format.parts.length) {
          var year = date.getFullYear(), day = date.getDate(), month = date.getMonth();
          for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
            val = parseInt(parts[i], 10) || 1;
            switch (format.parts[i]) {
              case 'dd':
              case 'd':
                day = val;
                date.setDate(val);
                break;
              case 'mm':
              case 'm':
                month = val - 1;
                date.setMonth(val - 1);
                break;
              case 'yy':
                year = 2000 + val;
                date.setFullYear(2000 + val);
                break;
              case 'yyyy':
                year = val;
                date.setFullYear(val);
                break;
              }
          }
          date = new Date(year, month, day, 0, 0, 0);
        }
        return date;
      },
      //把日期格式化日期字符串(format的格式)
      formatDate: function (date, format) {
        var val = {
          d: date.getDate(),
          m: date.getMonth() + 1,
          yy: date.getFullYear().toString().substring(2),
          yyyy: date.getFullYear()
        };
        val.dd = (val.d < 10 ? '0' : '') + val.d;
        val.mm = (val.m < 10 ? '0' : '') + val.m;
        var date = [];
        for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
          date.push(val[format.parts[i]]);
        }
        return date.join(format.separator);
      }
    };

    假设现在你有一个input元素需要绑定日历控件,那么只需要var date = new CCalendar(input元素,{})。这时将调用create方法创建日历,但是不显示,当input元素获得焦点时,就会触发show方法,显示出来。你可以在第二个参数中,传入json对象,比如:maxDate(可选择的最大日期),minDate(可选择的最小日期),lang(语言版本,中文,英文),onSelect(选择日期前,触发的方法),onHide(隐藏日期后,触发的方法),onSelectBack(选择日期后,触发的方法)等属性值。

    如果你需要弄成jQuery插件,或者弄到sea.js模块加载中去,请看:http://www.cnblogs.com/chaojidan/p/4213942.html

    加油!

  • 相关阅读:
    jquery冲突细节
    最懂中文的H5前端框架amazeUI
    IT Girl
    json_encode注意
    YII2 Activedataprovider 类分页的使用
    Yii框架,在页面输出执行sql语句,方便调试
    yii2的GridView和ActiveDataProvider具体使用
    文件压缩工具类
    将dubbo中使用的动态代理作为工具类
    spring中使用动态代理(AOP)
  • 原文地址:https://www.cnblogs.com/chaojidan/p/4140725.html
Copyright © 2020-2023  润新知