知识大全 Javascript日期级联组件代码分析及demo
Posted 知
篇首语:别裁伪体亲风雅,转益多师是汝师。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Javascript日期级联组件代码分析及demo相关的知识,希望对你有一定的参考价值。
Javascript日期级联组件代码分析及demo 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
最近研究下JS日期级联效果 感觉还不错 然后看了下kissy也正好有这么一个组件 也看了下源码 写的还不错 通过google最早是在 年 淘宝的虎牙(花名)用原审JS写了一个(貌似据说是从YUI那边重构下的) 具体的可以看他的 博客园 感觉kissy组件源码 思路也是和YUI类似 所以我今天的基本思路也和他们的一样 只是通过自己分析下及用自己的方式包装下
基本原理
传参中有 &# ;年份下拉框dom节点&# ; &# ;月份下拉框dom节点&# ; &# ;天数下拉框dom节点&# ; "开始日期" "结束日期" "默认日期"配置项
如果开始传参日期为空 那么默认是从" "开始
如果"结束日期为空" 那么默认结束日期为当前的时间
如果默认日期为空 那么默认日期默认为当前的时间
月份对应的天数可以直接写死 如 _dayInMonth: [ ] ; 分别为 月份到 月份的各个月份的默认天数 当然还有 月份闰年 天的情况 待会在代码中会有判断的
分别渲染出年份区间 月份区间 及相应的天数 (如果有默认的日期的话 且默认日期大于或者等于开始日期 且小于或者等于结束日期的话) 那么页面加载的时候 显示默认日期
绑定change事件 当切换到不同年份的时候 月份和天数也要分别渲染出来
基本配置项如下
对外提供的方法
getDate() 返回当前时间 格式为yyyy mm dd
getYear() 返回当前的年份
getMonth() 返回当前的月份
getDay() 返回当前月份中的天数
JSFiddle demo链接如下
查看demo 请点击我!
下面代码分析如下
初始化调用init方法 分别获取开始时间 结束时间 默认时间的 "年 月 天" 如下代码
// 开始时间可选 如果为空的话 那么默认开始时间是 if(_config dateStart != ) this startDate = y: new Date(_config dateStart) getFullYear() m: new Date(_config dateStart) getMonth() + d: new Date(_config dateStart) getDate() ; else var dateStart = / / ; this startDate = y: new Date(dateStart) getFullYear() m: new Date(dateStart) getMonth() + d: new Date(dateStart) getDate() ; // dateEnd 默认为空 如果没有传入的话 就取当前的时间 if(_config dateEnd == ) this endDate = y: new Date() getFullYear() m: new Date() getMonth() + d: new Date() getDate() ; else this endDate = y: new Date(_config dateEnd) getFullYear() m: new Date(_config dateEnd) getMonth() + d: new Date(_config dateEnd) getDate() ; // 默认时间可选 如果默认时间为空的话 那么就取当前的时间 if(_config dateDefault != ) this defaultDate = y: new Date(_config dateDefault) getFullYear() m: new Date(_config dateDefault) getMonth() + d: new Date(_config dateDefault) getDate() ; else this defaultDate = y: new Date() getFullYear() m: new Date() getMonth() + d: new Date() getDate() ; // 判断时间是否合理 if((Date parse(self _changeFormat(_config dateStart)) > Date parse(self _changeFormat(_config dateEnd))) || (Date parse(self _changeFormat(_config dateDefault)) > Date parse(self _changeFormat(_config dateEnd)))) return;
渲染下拉框的年份 调用 y = self _renderYear();这个方法
获取年份的区间范围 获取方法就是 获取开始时间的年份 和 结束时的年份 如下代码
/* * 获取年份的范围 最小 最大 * @method _getYearRange * @return min max */ _getYearRange: function() var self = this _config = nfig; return min: self startDate y max: self endDate y
接着渲染年份 从最近的年份开始渲染 如果有默认的年份 且 满足条件的话 那么默认的年份显示出来 如下代码
/* * 渲染年份下拉框 * @method _renderYear * private */ _renderYear: function() var self = this _config = nfig _cache = self cache; var nodeyear = $(_config nodeYear)[ ] y = self defaultDate y range option; if(nodeyear) range = self _getYearRange(); for(var i = range max; i >= range min; i ) option = new Option(i i); // 如果有默认年份的话 if(i == y) option selected = true; // 兼容所有浏览器 插入到最后 nodeyear add(option undefined); $(nodeyear) attr( year y); return y;
接着渲染月份 调用这个方法 y参数就是刚刚返回的年份 m = self _renderMonth(y);
同理 渲染月份也要获取月份的范围 默认都是从 月份到 月份 但是也有列外 比如如下 个判断
/* * 获取月份的范围 * @method _getMonthRange * @param y Number */ _getMonthRange: function(y) var self = this _config = nfig; var startDate = self startDate endDate = self endDate min = max = ; /* * 如果默认年份等于开始年份的话 那么月份最小取得是开始的月份 * 因为如果开始是 如果默认的是 那么最小月份肯定取得是 * 因为默认时间不可能小于开始时间 */ if(y == startDate y) // 开始年份 min = startDate m; /* * 同理 如果默认年份等于 那么取得是当前的年份(endDate未传的情况下) * 那么最大的肯定取得是当前年份的 月份 不可能取的是 因为只渲染出当前月份出来 * 后面的月份没有渲染出来 */ if(y == endDate y) max = endDate m; return min: min max: max
知道月份的范围后 然后根据上面的年份渲染相应的月份 代码如下
/* * 根据年份 渲染所有的月份 * @method _renderMonth * @param y 年份 */ _renderMonth: function(y) var self = this _config = nfig; var nodeMonth = $(_config nodeMonth)[ ] m = $(nodeMonth) attr( month ) || self defaultDate m range option t = false; if(nodeMonth) range = self _getMonthRange(y); nodeMonth innerHTML = ; for(var i = range min; i <= range max; i++) option = new Option(self bitExpand(i) self bitExpand(i)); // 如果有默认的月份的话 if(i == m) option selected = true; m = i; t = true; // 兼容所有浏览器 插入到最后 nodeMonth add(option undefined); if(!t) m = range min; $(nodeMonth) attr( month m); return m;
上面的代码 用了这句判断 m = $(nodeMonth) attr(&# ;month&# ;) || self defaultDate m 默认情况下 也就是说页面一加载的时候 可以获取默认的月份 但是当我触发change事件后 我取的月份 是从m = $(nodeMonth) attr(&# ;month&# ;) 这个里面取得 上面代码 nodeMonth innerHTML = &# ;&# ;; 也是为了change时候 请清空掉 然后重新生成的
渲染天数 通过这个方法 self _renderDay(y m);
渲染天数 同理也要获得相应的天数 调用_getDayRange方法 此方法中有判断是闰年的情况的 如下代码
/* * 获得天数的范围 * @method _getDayRange * @param y m number number */ _getDayRange: function(y m) var self = this _config = nfig _cache = self cache; var startDate = self startDate endDate = self endDate min = max; if(m) if(m == ) max = self _isLeapYear(y) ? : ; else max = _cache _dayInMonth[m ]; // 如果年月份都等于开始日期的话 那么min也等于开始日 if(y == startDate y && m == startDate m) min = startDate d; // 如果年月份都等于结束日期的话 那么max也等于结束日 if(y == endDate y && m == endDate m) max = endDate d; return min: min max: max
接着渲染天数的方法如下
_renderDay: function(y m) var self = this _config = nfig; var nodeDay = $(_config nodeDay)[ ] d = $(nodeDay) attr( day ) || self defaultDate d range option t = false; if(nodeDay) range = self _getDayRange(y m); nodeDay innerHTML = ; for(var i = range min; i <= range max; i++) option = new Option(self bitExpand(i) self bitExpand(i)); // 如果有默认的天数的话 if(i == d) option selected = true; d = i; t = true; // 兼容所有浏览器 插入到最后 nodeDay add(option undefined); if(!t) d = range min; $(nodeDay) attr( day d); return d;
最后用绑定change事件 调用_bindEnv方法 如
/* * 绑定所有事件 * @method _bindEnv * private */ _bindEnv:function() var self = this _config = nfig _cache = self cache; //年份改变 $(_config nodeYear) change(function(e) var y = e target value m = self _renderMonth(y); self _renderDay(y m); $(_config nodeYear) attr( year y); ); //月份改变 $(_config nodeMonth) change(function(e) var m = e target value y = $(_config nodeYear) attr( year ); self _renderDay(y m); $(_config nodeMonth) attr( month m); ); //日期改变 $(_config nodeDay) change(function(e) var d = e target value; $(_config nodeDay) attr( day d); );
HTML代码如下
<label>出生日期: </label> <select id= year > </select>年 <select id= month > </select>月 <select id= day > </select>日 <ul> <li><em>getDate</em> : <button id= testDate >日期</button><input id= textDate /></li> <li><em>getYear</em> : <button id= testYear >年</button><input id= textYear /></li> <li><em>getMonth</em> : <button id= testMonth >月</button><input id= textMonth /></li> <li><em>getDay</em> : <button id= testDay >日</button><input id= textDay /></li> </ul>
JS代码如下
/** * JS日期级联组件 * @constructor DateCascade * @param object 可配置的对象 * @time * @author */ function DateCascade(options) nfig = nodeYear : #year // 年份下拉框dom nodeMonth : #month // 月份下拉框dom nodeDay : #day // 日期下拉框dom dateStart : // 开始日期 dateEnd : // 结束日期(可选 默认为空就为当前时间) dateDefault : // 默认日期 ; this cache = _dayInMonth: [ ] // 月份对应的天数 ; this init(options); DateCascade prototype = constructor: DateCascade init: function(options) nfig = $ extend(nfig options || ); var self = this _config = nfig _cache = self cache; var y m; /* 开始时间 和 截至时间 默认时间*/ // 开始时间可选 如果为空的话 那么默认开始时间是 if(_config dateStart != ) this startDate = y: new Date(_config dateStart) getFullYear() m: new Date(_config dateStart) getMonth() + d: new Date(_config dateStart) getDate() ; else var dateStart = / / ; this startDate = y: new Date(dateStart) getFullYear() m: new Date(dateStart) getMonth() + d: new Date(dateStart) getDate() ; // dateEnd 默认为空 如果没有传入的话 就取当前的时间 if(_config dateEnd == ) this endDate = y: new Date() getFullYear() m: new Date() getMonth() + d: new Date() getDate() ; else this endDate = y: new Date(_config dateEnd) getFullYear() m: new Date(_config dateEnd) getMonth() + d: new Date(_config dateEnd) getDate() ; // 默认时间可选 如果默认时间为空的话 那么就取当前的时间 if(_config dateDefault != ) this defaultDate = y: new Date(_config dateDefault) getFullYear() m: new Date(_config dateDefault) getMonth() + d: new Date(_config dateDefault) getDate() ; else this defaultDate = y: new Date() getFullYear() m: new Date() getMonth() + d: new Date() getDate() ; // 判断时间是否合理 if((Date parse(self _changeFormat(_config dateStart)) > Date parse(self _changeFormat(_config dateEnd))) || (Date parse(self _changeFormat(_config dateDefault)) > Date parse(self _changeFormat(_config dateEnd)))) return; // 渲染年份 y = self _renderYear(); // 渲染月份 m = self _renderMonth(y); // 渲染天 self _renderDay(y m); // 所有绑定事件 self _bindEnv(); /* * 渲染年份下拉框 * @method _renderYear * private */ _renderYear: function() var self = this _config = nfig _cache = self cache; var nodeyear = $(_config nodeYear)[ ] y = self defaultDate y range option; if(nodeyear) range = self _getYearRange(); for(var i = range max; i >= range min; i ) option = new Option(i i); // 如果有默认年份的话 if(i == y) option selected = true; // 兼容所有浏览器 插入到最后 nodeyear add(option undefined); $(nodeyear) attr( year y); return y; /* * 根据年份 渲染所有的月份 * @method _renderMonth * @param y 年份 */ _renderMonth: function(y) var self = this _config = nfig; var nodeMonth = $(_config nodeMonth)[ ] m = $(nodeMonth) attr( month ) || self defaultDate m range option t = false; if(nodeMonth) range = self _getMonthRange(y); nodeMonth innerHTML = ; for(var i = range min; i <= range max; i++) option = new Option(self bitExpand(i) self bitExpand(i)); // 如果有默认的月份的话 if(i == m) option selected = true; m = i; t = true; // 兼容所有浏览器 插入到最后 nodeMonth add(option undefined); if(!t) m = range min; $(nodeMonth) attr( month m); return m; _renderDay: function(y m) var self = this _config = nfig; var nodeDay = $(_config nodeDay)[ ] d = $(nodeDay) attr( day ) || self defaultDate d range option t = false; if(nodeDay) range = self _getDayRange(y m); nodeDay innerHTML = ; for(var i = range min; i <= range max; i++) option = new Option(self bitExpand(i) self bitExpand(i)); // 如果有默认的天数的话 if(i == d) option selected = true; d = i; t = true; // 兼容所有浏览器 插入到最后 nodeDay add(option undefined); if(!t) d = range min; $(nodeDay) attr( day d); return d; /* * 绑定所有事件 * @method _bindEnv * private */ _bindEnv:function() var self = this _config = nfig _cache = self cache; //年份改变 $(_config nodeYear) change(function(e) var y = e target value m = self _renderMonth(y); self _renderDay(y m); $(_config nodeYear) attr( year y); ); //月份改变 $(_config nodeMonth) change(function(e) var m = e target value y = $(_config nodeYear) attr( year ); self _renderDay(y m); $(_config nodeMonth) attr( month m); ); //日期改变 $(_config nodeDay) change(function(e) var d = e target value; $(_config nodeDay) attr( day d); ); /* * 获取年份的范围 最小 最大 * @method _getYearRange * @return min max */ _getYearRange: function() var self = this _config = nfig; return min: self startDate y max: self endDate y /* * 获取月份的范围 * @method _getMonthRange * @param y Number */ _getMonthRange: function(y) var self = this _config = nfig; var startDate = self startDate endDate = self endDate min = max = ; /* * 如果默认年份等于开始年份的话 那么月份最小取得是开始的月份 * 因为如果开始是 如果默认的是 那么最小月份肯定取得是 * 因为默认时间不可能小于开始时间 */ if(y == startDate y) // 开始年份 min = startDate m; /* * 同理 如果默认年份等于 那么取得是当前的年份(endDate未传的情况下) * 那么最大的肯定取得是当前年份的 月份 不可能取的是 因为只渲染出当前月份出来 * 后面的月份没有渲染出来 */ if(y == endDate y) max = endDate m; return min: min max: max /* * 获得天数的范围 * @method _getDayRange * @param y m number number */ _getDayRange: function(y m) var self = this _config = nfig _cache = self cache; var startDate = self startDate endDate = self endDate min = max; if(m) if(m == ) max = self _isLeapYear(y) ? : ; else max = _cache _dayInMonth[m ]; // 如果年月份都等于开始日期的话 那么min也等于开始日 if(y == startDate y && m == startDate m) min = startDate d; // 如果年月份都等于结束日期的话 那么max也等于结束日 if(y == endDate y && m == endDate m) max = endDate d; return min: min max: max /* * 判断是否是闰年 */ _isLeapYear: function(y) return (y % === && y % !== ) || (y % === ); /** * 是否是Date格式 * @method _isDate * @param Date d * @private * @return Boolean */ _isDate: function(d) return Object prototype toString call(d) === [object Date] && d toString() !== Invalid Date && !isNaN(d); /* * 小于 的数字加零 * @method bitExpand */ bitExpand: function(num) var num = num * ; if(/d/ test(num)) if(num < ) return + num; else return num; /* * 判断开始日期 默认日期 结束日期的格式 */ _changeFormat: function(date) return date replace(/ /g / ); /* * 获取日期 */ getDate: function() var self = this _config = nfig; var year = $(_config nodeYear) attr( year ) month = $(_config nodeMonth) attr( month ) day = $(_config nodeDay) attr( day ); return (year + + self bitExpand(month) + + self bitExpand(day)); /* * 获取年份 */ getYear: function() var self = this _config = nfig; var year = $(_config nodeYear) attr( year ); return year; /* * 获取月份 */ getMonth: function() var self = this _config = nfig; var month = $(_config nodeMonth) attr( month ); return month; /* * 获取天数 */ getDay: function() var self = this _config = nfig; var day = $(_config nodeDay) attr( day ); return day;
初始化方式如下
// 初始化 $(function() var date = new DateCascade(); $( #testDate ) click(function(e) $( #textDate ) val(date getDate()); ); $( #testYear ) click(function(e) $( #textYear ) val(date bitExpand(date getYear())); ); $( #testMonth ) click(function(e) $( #textMonth ) val(date bitExpand(date getMonth())); ); $( #testDay ) click(function(e) $( #textDay ) val(date bitExpand(date getDay())); ); );
cha138/Article/program/Web/201405/30982相关参考
JavaScript访问JSF组件的方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 先看下面
有两张表结构如下 Java代码 t_item &n
使用Decorator模式实现日期选择组件(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
使用Decorator模式实现日期选择组件(4) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 使用javascript过滤html的字符串(注释标记法)
本篇文章是对使用javascript过滤的字符串进行了详细的分析介绍需要的朋友参考下 复制代码代码如下:cha138/Article/program/Java/JSP/201311
Javascript日期格式化函数性能对比 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 最近开
知识大全 用JavaScript判断日期、数字、整数和特殊字符
用JavaScript判断日期、数字、整数和特殊字符 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
详解.NET4.0代码契约组件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 代码契约组件是对N
如何使用Javascript获取距今n天前的日期 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!本篇
摘要本文描述了如何用CodeAccessSecurity技术来保护代码使代码不致被恶意调用 作为一名NET开发人员你没日没夜地写代码你的组件运行在越来越多的机器上忽然有一天你发现你写的组件被引用