重构日期选择级联组件

编程入门 行业动态 更新时间:2024-10-24 23:20:07

重构日期选择级联<a href=https://www.elefans.com/category/jswz/34/1771375.html style=组件"/>

重构日期选择级联组件

这是一个很常见的日期选择级联组件,先看下效果:

View Code
  < div > 
< p >
< input type ="text" id ="birthday" name ="birthday" value ="2008/2/29" />
</ p >
</ div >
< script src =".js" ></ script >
< script >
window.onload = function () {
var date = new DateCascade( ' birthday ' );
};
</ script >

这个组件是基于Cubee里的相同组件Y.DateCascade改写的,由于原来的组件代码依赖于YUI过于繁琐及存在着一些bug,于是用原生js重构了一遍。以下是重构的过程的一些思路。

一、分析组件的结构及行为

其实这个组件的结构及行为很简单,不外乎是年月日间互相联动,动态改变select里的option个数及其值。

  1. 日期需要有一个上限及下限,比如从1900年1月1日开始,最多能选到2012年12月21日;
  2. 能根据不同的月份显示不同的天数,比如1月有31天可选,闰年的2月则只有29天可选等;
  3. 可以手动设定其默认选中的值;
  4. 最后一个特殊的地方,依赖一个input的文本框(业务需要),当JS失效时可以实现平稳退化,手动输入日期(当然可以不依赖这个,直接将select的功能抽取出来)。
二、配置参数

根据上边的结构分析,我们很容易想到组件的配置参数:

  1. dateStart:日期的下限,可选,默认为1900/01/01;
  2. dateEnd:日期的上限,可选,默认为当天;
  3. dateDefault:初始化时默认选中的日期,可选,可以为input里的日期值;
  4. id:input的id,js将会将select动态加到input节点的后面。
组件的使用方法如下:
var date = new DateCascade(id, {dateStart: xxxx/xx/xx,dateEnd: xxxx/xx/xx,dateDefault: xxxx/xx/xx
});
三、对外提供的接口

师兄说过,开发一个组件,先想好其接口方法,再思考实现其功能的逻辑方法。这个组件提供了一些常用的方法:

  1. render:渲染结构,这个方法在初始化init的时候调用了一次,后面可以多次调用更改其参数重新渲染结构(不影响之前绑定过的事件);
    //上下限均为默认值,初始化时已经调用过一次render方法
    var dt = new DateCascade('birthday',{});
    //重新设置上下限及默认选中值
    dt.render({dateStart: '1930/01/01',dateEnd: '2012/12/21',dateDefault: '1989/11/05'
    });
    
  2. renderYear,renderMonth,renderDay:分别渲染年月日的select结构;
  3. setNewDate:设置新的选中日期,参数形式有两种:
    dt.setNewDate('2011/01/20');// 传进Date值
    dt.setNewDate('2011', '01', '20'); //按年月日传进参数,主要考虑到传进的年月日可能有空值
    
  4. setNewYear,setNewMonth,setNewDay:分别设置新的年月日;
四、逻辑的实现

实现逻辑的思路很简单:知道年月日的可选择范围(如1月的可选天数范围为1-31) -> 渲染相应的日期结构 -> 设置选中日期。

所以起始点在于获取年月日的可选择范围:

        /*** 获取年份区间* @method _getYearRange* @return {Object}* @private*/_getYearRange: function(){var that = this;return {min: that._dsYear,max: that._deYear};},/*** 获取月份区间* @method _getMonthRange* @param y {Number}* @return {Object}* @private*/_getMonthRange: function(y){var that = this, min = 1, max = 12;if (y == that._dsYear) {min = that._dsMonth;}if (y == that._deYear) {max = that._deMonth;}return {min: min,max: max};},/*** 获取天数区间* @method _getMonthRange* @param y {Number}* @param m {Number}* @return {Object}* @private*/_getDayRange: function(y, m){var that = this, min = 1, max = 31;if (m) {if (m != 2) {max = that._dayInMonth[m - 1];}else {max = that._isLeapYear(y) ? 29 : 28;}if (y == that._dsYear && m == that._dsMonth) {min = that._dsDay;}if (y == that._deYear && m == that._deMonth) {max = that._deDay;}}return {min: min,max: max};}
然后粗略浏览一下实现整个组件的逻辑方法:(细节请看 这里)
var DateCascade = function(){//构造函数function DateCascade(){this._init.apply(this, arguments);}//函数原型DateCascade.prototype = {constructor: DateCascade,_init: function(id, config){//初始化  },_buildParam: function(config){//设置参数},_bindEvent: function(){//绑定change事件},render: function(config){//渲染结构},_isLeapYear: function(y){//是否是闰年},_isDate: function(d){//检查是否是正确的Date格式},_checkDate: function(date){//是否是正确的Date或可形成Date的字符串},    setNewDate: function(/*y, m, d*/) {//设置新日期},setNewYear: function(y, l){//设置新年份},setNewMonth: function(m, l){//设置新月份},setNewDay: function(d){//设置新天数},renderYear: function(){//渲染年份},renderMonth: function(y){//渲染月份},renderDay: function(y, m){//渲染天数},_getYearRange: function(){//获取年份区间},_getMonthRange: function(y){//获取月份区间},_getDayRange: function(y, m){//获取天数区间}};return DateCascade;
}();
五、其他
其他的一些细节及应该注意的地方
  1. render年月日结构时使用原生的select.add(new Option(text, value), undefined)的形式添加选项,速度快(原来的组件使用YUI方法添加的,IE6下会出现渲染延迟的bug);
  2. 将日期值转成数值时要用parseInt(v, 10),别忘了后面的参数10,因为如果v是以0开头的数最后会转成八进制数,而日期经常会出现以0开头的数;
  3. 选中值的时候可以直接使用select.value = v的形式,而不用一个个option的匹配;
  4. 用3的方法选值,如果选项里没有对应的值,不同浏览器的处理不一样,除IE外的浏览器会默认选中第一个选项,而IE不会选中任何值,因此要hack一下;
  5. 添加了getSelectedDate(取得选中日期的值)和updateInput(更新input里的值)的方法;
  6. 没有设置回调函数的功能(个人觉得没必要)
六、下载
demo及源码下载(含YUI新版本)

转载于:.html

更多推荐

重构日期选择级联组件

本文发布于:2024-02-17 15:15:07,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1694487.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组件   重构   日期   级联

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!