一. 效果图

二. 功能说明

  1. 支持切换年份,月份。

  2. 支持点击选中日期,也可以点击确定选择日期。

三. 使用方法

  1. 添加Input

  在你的页面中添加Input输入框。可以再html里,也可以JS动态加载。

  我这里使用的时Input-group形式的输入框,是JS加载的。

  一般使用的话,直接写个input输入框就行。

<div class="item item-buydate input-group">
<span class="input-group-span no-border-right" id="buydate-span">申购成交时间</span>
<input class="txt-input txt-buydate no-border-left text-right" type="text" placeholder="请选择申购日期" readonly>
</div>

2. 调用方法

  可选择项目:最大、最小日期。

$('.item-buydate').mdater();

3. 源代码

  注意:注意更改代码中的图片资源路径。

(function($) {
$.fn.mdater = function(config) {
var defaults = {
maxDate: null,
minDate: new Date(1970, 0, 1)
};
var option = $.extend(defaults, config);
//window.console && console.log(this);
var input = this; //通用函数
var F = {
//计算某年某月有多少天
getDaysInMonth: function(year, month) {
return new Date(year, month + 1, 0).getDate();
},
//计算某月1号是星期几
getWeekInMonth: function(year, month) {
return new Date(year, month, 1).getDay();
},
getMonth: function(m) {
return ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'][m];
},
//计算年某月的最后一天日期
getLastDayInMonth: function(year, month) {
return new Date(year, month, this.getDaysInMonth(year, month));
}
} //为$扩展一个方法,以配置的方式代理事件
$.fn.delegates = function(configs) {
el = $(this[0]);
for (var name in configs) {
var value = configs[name];
if (typeof value == 'function') {
var obj = {};
obj.click = value;
value = obj;
};
for (var type in value) {
el.delegate(name, type, value[type]);
}
}
return this;
} var mdater = {
value: {
year: '',
month: '',
date: ''
},
lastCheckedDate: '',
init: function() {
this.initListeners();
},
renderHTML: function() {
var $html = $('<div class="md_mask"></div><div class="md_panel"><div class="md_head"><div class="md_selectarea"><a class="md_prev change_year" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_left.png"></a><a class="md_headtext yeartag" href="javascript:void(0);"></a><a class="md_next change_year" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_right.png"></a></div><div class="md_selectarea"><a class="md_prev change_month" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_left.png"></a><a class="md_headtext monthtag" href="javascript:void(0);">月</a> <a class="md_next change_month" href="javascript:void(0);"><img style="vertical-align:middle;height:14px;" src="../images/mdate_right.png"></a></div></div><div class="md_body"><ul class="md_weekarea"><li>日</li><li>一</li><li>二</li><li>三</li><li>四</li><li>五</li><li>六</li></ul><ul class="md_datearea in"></ul></div><div class="md_foot"><a href="javascript:void(0);" class="md_ok">确定</a> <a href="javascript:void(0);" class="md_cancel">取消</a></div></div>');
if ($('.md_mask').length == 0) { $(document.body).append($html); }
return $html;
},
_showPanel: function(container) {
this.refreshView();
$('.md_panel, .md_mask').addClass('show');
},
_hidePanel: function() {
//$('.md_panel, .md_mask').removeClass('show');
$('.md_panel, .md_mask').remove();
},
_changeMonth: function(add, checkDate) { //先把已选择的日期保存下来
this.saveCheckedDate(); var monthTag = $('.md_selectarea').find('.monthtag'),
num = ~~monthTag.data('month') + add;
//月份变动发生了跨年
if (num > 11) {
num = 0;
this.value.year++;
$('.yeartag').text(this.value.year).data('year', this.value.year);
} else if (num < 0) {
num = 11;
this.value.year--;
$('.yeartag').text(this.value.year).data('year', this.value.year);
} var nextMonth = F.getMonth(num) + '月';
monthTag.text(nextMonth).data('month', num);
this.value.month = num;
if (checkDate) {
this.value.date = checkDate;
} else {
//如果有上次选择的数据,则进行赋值
this.setCheckedDate();
}
this.updateDate(add);
},
_changeYear: function(add) {
//先把已选择的日期保存下来
this.saveCheckedDate(); var yearTag = $('.md_selectarea').find('.yeartag'),
num = ~~yearTag.data('year') + add;
yearTag.text(num + '年').data('year', num);
this.value.year = num; this.setCheckedDate(); this.updateDate(add);
},
//保存上一次选择的数据
saveCheckedDate: function() {
if (this.value.date) {
this.lastCheckedDate = {
year: this.value.year,
month: this.value.month,
date: this.value.date
}
}
},
//将上一次保存的数据恢复到界面
setCheckedDate: function() {
if (this.lastCheckedDate && this.lastCheckedDate.year == this.value.year && this.lastCheckedDate.month == this.value.month) {
this.value.date = this.lastCheckedDate.date;
} else {
this.value.date = '';
}
},
//根据日期得到渲染天数的显示的HTML字符串
getDateStr: function(y, m, d) {
var dayStr = '';
//计算1号是星期几,并补上上个月的末尾几天
var week = F.getWeekInMonth(y, m);
var lastMonthDays = F.getDaysInMonth(y, m - 1);
for (var j = week - 1; j >= 0; j--) {
dayStr += '<li class="prevdate" data-day="' + (lastMonthDays - j) + '">' + (lastMonthDays - j) + '</li>';
}
//再补上本月的所有天;
var currentMonthDays = F.getDaysInMonth(y, m);
//判断是否超出允许的日期范围
var startDay = 1,
endDay = currentMonthDays,
thisDate = new Date(y, m, d),
firstDate = new Date(y, m, 1);
lastDate = new Date(y, m, currentMonthDays),
minDateDay = option.minDate.getDate(); if (option.minDate > lastDate) {
startDay = currentMonthDays + 1;
} else if (option.minDate >= firstDate && option.minDate <= lastDate) {
startDay = minDateDay;
} if (option.maxDate) {
var maxDateDay = option.maxDate.getDate();
if (option.maxDate < firstDate) {
endDay = startDay - 1;
} else if (option.maxDate >= firstDate && option.maxDate <= lastDate) {
endDay = maxDateDay;
}
} //将日期按允许的范围分三段拼接
for (var i = 1; i < startDay; i++) {
dayStr += '<li class="disabled" data-day="' + i + '">' + i + '</li>';
}
for (var j = startDay; j <= endDay; j++) {
var current = '';
if (y == this.value.year && m == this.value.month && d == j) {
current = 'current';
}
dayStr += '<li class="' + current + '" data-day="' + j + '">' + j + '</li>';
}
for (var k = endDay + 1; k <= currentMonthDays; k++) {
dayStr += '<li class="disabled" data-day="' + k + '">' + k + '</li>';
} //再补上下个月的开始几天
var nextMonthStartWeek = (currentMonthDays + week) % 7;
if (nextMonthStartWeek !== 0) {
for (var i = 1; i <= 7 - nextMonthStartWeek; i++) {
dayStr += '<li class="nextdate" data-day="' + i + '">' + i + '</li>';
}
} return dayStr;
},
updateDate: function(add) {
var dateArea = $('.md_datearea.in');
if (add == 1) {
var c1 = 'out_left';
var c2 = 'out_right';
} else {
var c1 = 'out_right';
var c2 = 'out_left';
}
var newDateArea = $('<ul class="md_datearea ' + c2 + '"></ul>');
newDateArea.html(this.getDateStr(this.value.year, this.value.month, this.value.date));
$('.md_body').append(newDateArea);
setTimeout(function() {
newDateArea.removeClass(c2).addClass('in');
dateArea.removeClass('in').addClass(c1);
}, 0); },
//每次调出panel前,对界面进行重置
refreshView: function() {
if (this.input.hasClass('input-group')) {
var initVal = this.input.children('input').val();
} else {
var initVal = this.input.val();
}
var date = null;
if (initVal) {
var arr = initVal.split('-');
date = new Date(arr[0], arr[1] - 1, arr[2]);
} else {
date = new Date();
}
var y = this.value.year = date.getFullYear(),
m = this.value.month = date.getMonth(),
d = this.value.date = date.getDate();
$('.yeartag').text(y).data('year', y);
$('.monthtag').text(F.getMonth(m) + '月').data('month', m);
var dayStr = this.getDateStr(y, m, d);
$('.md_datearea').html(dayStr);
},
input: null, //暂存当前指向input
initListeners: function() {
var _this = this;
input.on('click', function() {
_this.input = $(this); //暂存当前指向input
if ($('.md_mask').length) {
_this._hidePanel();
} else {
_this.renderHTML();
var panel = $('.md_panel'),
mask = $('.md_mask');
_this.afterShowPanel(mask, panel);
setTimeout(function() {
_this._showPanel();
}, 50);
}
});
},
saveValueToInput: function() {
var _this = this;
var monthValue = ~~_this.value.month + 1;
if (monthValue < 10) {
monthValue = '0' + monthValue;
}
var dateValue = _this.value.date;
if (dateValue === '') {
dateValue = _this.value.date = 1;
}
if (dateValue < 10) {
dateValue = '0' + dateValue;
}
if (_this.input.hasClass('input-group')) {
_this.input.children('input').val(_this.value.year + '-' + monthValue + '-' + dateValue);
_this.input.children('input').trigger('input');
} else {
_this.input.val(_this.value.year + '-' + monthValue + '-' + dateValue);
_this.input.trigger('input');
}
_this._hidePanel();
},
afterShowPanel: function(mask, panel) {
var _this = this;
mask.on('click', function() {
_this._hidePanel();
});
panel.delegates({
'.change_month': function() {
var add = $(this).hasClass('md_next') ? 1 : -1;
_this._changeMonth(add);
},
'.change_year': function() {
var add = $(this).hasClass('md_next') ? 1 : -1;
_this._changeYear(add);
},
'.out_left, .out_right': {
'webkitTransitionEnd': function() {
$(this).remove();
}
},
'.md_datearea li': function() {
var $this = $(this);
if ($this.hasClass('disabled')) {
return;
}
_this.value.date = $this.data('day');
//判断是否点击的是前一月或后一月的日期
var add = 0;
if ($this.hasClass('nextdate')) {
add = 1;
} else if ($this.hasClass('prevdate')) {
add = -1;
}
if (add !== 0) {
_this._changeMonth(add, _this.value.date);
} else {
$this.addClass('current').siblings('.current').removeClass('current');
_this.saveValueToInput();
}
},
'.md_cancel': function() {
_this._hidePanel();
},
'.md_ok': function() {
_this.saveValueToInput();
}
});
}
}
mdater.init();
}
})(window.Zepto || window.jQuery);
a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
} .md_mask {
width: 100%;
height: 100%;
-moz-transition: opacity .5s linear 0s;
-webkit-transition: opacity .5s linear 0s;
-o-transition: opacity .5s linear 0s;
-ms-transition: opacity .5s linear 0s;
transition: opacity .5s linear 0s;
position: absolute;
top:;
left:;
display: block;
visibility: hidden;
background: #000;
opacity:;
z-index:;
} .md_mask.show {
visibility: visible;
opacity: 0.25;
} .md_panel {
-moz-transition: -moz-transform .3s ease-in-out 0s;
-ms-transition: -ms-transform .3s ease-in-out 0s;
-webkit-transition: -webkit-transform .3s ease-in-out 0s;
-o-transition: -o-transform .3s ease-in-out 0s;
transition: transform .3s ease-in-out 0s;
-ms-transform: translate3d(0, 100%, 0);
-moz-transform: translate3d(0, 100%, 0);
-webkit-transform: translate3d(0, 100%, 0);
-o-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
position: fixed;
bottom:;
left:;
width: 100%;
height: auto;
z-index:;
background-color: #F7F7F7;
font-family: Tahoma, arial, verdana, sans-serif;
-webkit-user-select: none;
} .md_panel.show {
-ms-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
} .md_panel a {
text-decoration: none;
} .md_selectarea {
display: inline-block;
width: 50%;
position: relative;
} .md_head {
height: 40px;
line-height: 40px;
} .md_body {
position: relative;
height: 268px;
} .md_headtext {
display: inline-block;
width: 100%;
text-align: center;
font-size: 1.125em;
color: #333;
} .md_prev,
.md_next {
position: absolute;
top:;
font-family: arial;
font-size: 1.6em;
display: inline-block;
width: 40px;
height: 40px;
text-align: center;
} .md_prev {
left:;
} .md_next {
right:;
} .md_weekarea {
margin:;
padding:;
list-style-type: none;
overflow: hidden;
} .md_weekarea li,
.md_datearea li {
display: inline-block;
float: left;
width: 14.2857%;
font-size: .8125em;
font-weight:;
text-align: center;
line-height: 3.31em;
} .md_weekarea li,
.md_prev,
.md_next {
color: #5b5b5b;
} .md_datearea {
position: absolute;
width: 100%;
list-style-type: none;
margin:;
padding:;
overflow: hidden;
-webkit-transition: -webkit-transform .2s ease-in;
-webkit-transform: translate3d(0, 0, 0);
} .md_datearea li.current {
background-color: #872F9F;
color: #FFF;
border-radius: 4px;
} .md_datearea li span {
display: inline-block;
width: 100%;
height: 100%;
} .md_datearea li span.current {
background-color: #872F9F;
color: #FFF;
} .md_foot {
margin-top: 0.5em;
margin-bottom: 1em;
text-align: center;
} .md_ok,
.md_cancel {
display: -moz-inline-stack;
display: inline-block;
*display: inline;
*zoom:;
width: 9em;
height: 2.5em;
line-height: 2.5em;
border-radius: 4px;
} .md_ok {
color: #fff;
background-color: #872F9F;
} .md_cancel {
color: #fff;
margin-left: 1em;
background-color: #C6C6C6;
} .out_left {
-webkit-transform: translate3d(-100%, 0, 0);
} .out_right {
-webkit-transform: translate3d(100%, 0, 0);
} .prevdate,
.nextdate {
color: #999;
} .disabled {
color: #C6C6C6;
}

移动端-手机端-日历选择控件(支持Zepto和JQuery)的更多相关文章

  1. 移动端日历选择控件(支持Zepto和JQuery)

    移动端日历选择控件(支持Zepto和JQuery) <!DOCTYPE html> <html> <head> <meta charset="utf ...

  2. 移动端翻页插件dropload.js(支持Zepto和jQuery)

    一. 声明 代码来源:github上的dropload项目. 二. 问题 dropload.js提供了最基本的上拉翻页,下拉刷新功能.对于由服务端一次返回所有数据的情况基本通用. 但是,需求往往不是服 ...

  3. js日历选择控件

    mydate97: http://www.my97.net/dp/demo/index.htm

  4. 记录 Ext 日历月份选择控件bug解决过程结果

    目录 背景 代码 背景 项目使用 Ext.NET 2.2.0.40838 , 对应 Ext JS4.2 版本. 结果 2017/3/31 号的时候偶然间点日历选择控件选择2月,10月等月份突然就跳到3 ...

  5. js组件开发-移动端地区选择控件mobile-select-area

    移动端地区选择控件mobile-select-area 由于之前的[js开源组件开发]js手机联动选择地区仿ios 开源git 很受欢迎,于是我又对其进行了一些优化,包括可选的范围变大了,添加了默认空 ...

  6. jquery mobiscroll移动端日期选择控件(无乱码)

    jquery mobiscroll移动端日期选择控件(无乱码) <pre><!DOCTYPE html><html lang="en">< ...

  7. 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

    本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.a ...

  8. 《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)

    1.简介 理想很丰满现实很骨感,在应用selenium实现web自动化时,经常会遇到处理日期控件点击问题,手工很简单,可以一个个点击日期控件选择需要的日期,但自动化执行过程中,完全复制手工这样的操作就 ...

  9. 页面日期选择控件--jquery ui datepicker 插件

    日期选择插件Datepicker是一个配置灵活的插件,我们可以自定义其展示方式,包括日期格式.语言.限制选择日期范围.添加相关按钮以及其它导航等.官方地址:http://docs.jquery.com ...

随机推荐

  1. 如何使用 highlight.js 高亮代码

    highlight 是一款简单易用的 web 代码高亮插件,可以自动检测编程语言并高亮,兼容各种框架,可以说是十分强大了.下面就简单介绍一下如何使用这款插件. 两种使用方式: 1. 手动选择主题,官网 ...

  2. python中用xpath匹配文本段落内容的技巧

    content = item.xpath('//div[@class="content"]/span')[0].xpath('string(.)') content = item. ...

  3. Django的ModelForm

    基于django.forms.ModelForm:与模型类绑定的Form 先定义一个ModelForm类,继承ModelForm类 from django.forms import ModelForm ...

  4. 解决mysql、vsftp远程连接速度慢的问题

    以 centOS 6.3(其他操作系统类似,同样适用)说明: 当我们的服务都配置正常的情况下,有时会出现连接速度慢而导致连接失败的问题 问题分析:这些情况一般都是DNS解析惹的祸 mysql连接速度慢 ...

  5. Go笔记-流程控制

    [if] if 是用于测试某个条件的语句,如果该条件(逻辑型或布尔型)成立,则会执行大括号内的代码,第一个大括号必须和if 或者else同行,否则非法 // 方式1 if condition { // ...

  6. IIS 加载 JSON 错误 404 解决办法

    MIME设置:在IIS的站点属性的HTTP头设置里,选MIME 映射中点击”文件类型”-”新类型”,添加一个文件类型:关联扩展名:*.json内容类型(MIME):application/x-java ...

  7. getopt for windows

    Glibc库里有个getopt用于解析命令行参数,挺方便的,下面的是别人从Glibc源码的获取的几个getopt相关的文件,已经将平台相关的修改掉,windows下可以调用,本来是要用没用到就没去看正 ...

  8. CF528D. Fuzzy Search [FFT]

    CF528D. Fuzzy Search 题意:DNA序列,在母串s中匹配模式串t,对于s中每个位置i,只要s[i-k]到s[i+k]中有c就认为匹配了c.求有多少个位置匹配了t 预处理\(f[i][ ...

  9. BZOJ 1025: [SCOI2009]游戏 [置换群 DP]

    传送门 题意:求$n$个数组成的排列变为升序有多少种不同的步数 步数就是循环长度的$lcm$..... 那么就是求$n$划分成一些数几种不同的$lcm$咯 然后我太弱了这种$DP$都想不出来.... ...

  10. 【转】 C/C++程序员必须熟练应用的开源项目

    作为一个经验丰富的C/C++程序员, 肯定亲手写过各种功能的代码, 比如封装过数据库访问的类, 封装过网络通信的类,封装过日志操作的类, 封装过文件访问的类, 封装过UI界面库等, 也在实际的项目中应 ...