您的位置:首页 > Web前端 > JavaScript

JS实现日历控件

2011-12-14 21:37 405 查看
的确,网上各种日历控件数不胜数,但也正是因为太多,所以选择起来也是件困难的事情。前不久,因为项目要求,就去试着找了些,但总感觉都不太完美,或者因为不够简单,不需要那么复杂的功能,或者因为不好用,不适合项目。我也选一个最接近的试着去读懂,然后想把它改成我所需要的,可惜的是,根本没法读懂,也不知道是我一直都习惯自己写,确实不擅长读别人的代码,还是确实因为其代码难读,其中取的变量名都是ABC之类的,纠结了。后来索性自己花时间写了一个,虽然不一定比得上网上流传的那些,但基本功能还是都有的,就在这里贴出来,算是给自己的一次肯定吧,呵呵。

先贴CSS部分:

#calendar {
position: relative;
font-size: 12px;
padding: 0;
z-index: 9998;
background-color: #FFF9DF;
border: 1px solid #999;
}#calendar .left {
float: left;
} #calendar .right {
float: right;
} #calendar .btn {
border-radius: 3px;
border: 1px solid #333;
background-color: #CCC;
cursor: pointer;
margin: 0 3px;
padding: 2px 5px;
color: #111;
}#calendar #year, #month {
display: inline-block;
padding: 2px 8px;
margin: 2px auto;
text-align: center;
cursor: pointer;
border: 1px solid #DDD;
} #calendar #date .week {
font-size: 12px;
text-align: center;
font-family: arial;
font-weight: bold;
margin: 0;
padding: 0 7px;
color: #FFF;
background-color: #999;
border: 1px solid #222;
} #calendar #date .week:hover {
color: #FFF;
border: 1px solid #222;
} #calendar #date td {
text-align: center;
margin: 0;
padding: 1px;
color: #111;
cursor: pointer;
background-color: #DDD;
border: 1px solid #DDD;
} #calendar #date td:hover {
color: #7A6E93;
background-color: #DFC9A7;
border: 1px solid #F90;
} #calendar #date .today {
background-color: #FC0;
}#calendar #date .before, #calendar #date .after {
color: #AAA;
background-color: #EEE;
} #selYear, #selMonth {
z-index: 9999;
background-color: #EEE;
border: 1px solid #DDD;
} #selYear span, #selMonth span {
display: block;
font-size: 10px;
height: 11px;
padding: 2px 8px;
text-align: center;
cursor: pointer;
border: 1px solid #DDD;
} #selYear span:hover, #selMonth span:hover {
background-color: #999;
} #selYear .preYear, #selYear .afterYear {
height: 1px;
background-color: #EBB;
} .bottom {
text-align: center;
cursor: pointer;
} .close {
padding: 3px 5px;;
border-radius: 12px;
border: 1px solid #F90;
background-color: #7A6E93;
color: #EEE;
} .close:hover {
border: 2px solid red;
}#time {
visibility: hidden;
padding: 3px;
text-align: center;
color: #FFE;
border-radius: 2px;
background-color: #8B96B9;
} #hour, #min, #sec {
padding: 2px 5px;
} #inputTime {
width: 15px;
padding: 0;
margin: 0 auto;
background-color: #8B96B9;
text-align: center;
z-index: 9999;
border: none;
}.selTime {
position: relative;
top: -2px;
font-size: 12px;
}


再贴上JS部分:

var week = new Array("日", "一", "二", "三", "四", "五", "六");
//初始化日期时间(可以传入一个Date参数)
function initDate(){
calClose = false;
var table = document.getElementById("date");
if (table == null) {
return;
}
var date = arguments[0];
if (arguments.length == 0) {
try {
var year = parseInt(document.getElementById("year").innerHTML);
var month = parseInt(document.getElementById("month").innerHTML) - 1;
date = new Date(year, month);
}
catch (e) {
date = new Date();
}
}

if (table.children.length != 0)
table.removeChild(table.children[0]);
var tr = table.insertRow(0);
for (var i = 0; i < 7; i++) {
var td = tr.insertCell(tr.cells.length);
initTd(td, week[i], "week");
}
var year = date.getFullYear();
document.getElementById("year").innerHTML = year + "";
var month = date.getMonth();
document.getElementById("month").innerHTML = (month + 1) + "";
var day = new Date(year, month + 1, 0).getDate();
var w = new Date(year, month, 1).getDay();
tr = table.insertRow(table.rows.length);
var lastDay = new Date(year, month, 0).getDate();
var today = -1;
if (arguments.length == 2) {
today = arguments[1];
}
for (i = 0; i < w; i++) {
var td = tr.insertCell(tr.cells.length);
initTd(td, lastDay - w + i, "before");
}
for (i = w; i < 7; i++) {
var td = tr.insertCell(tr.cells.length);
if (i - w + 1 == today) {
td.className = "today";
}
initTd(td, i - w + 1);
}
for (i = 7 - w + 1; i <= day; i++) {
if ((i - 8 + w) % 7 == 0) {
tr = table.insertRow(table.rows.length);
}
var td = tr.insertCell(tr.cells.length);
if (i == today) {
td.className = "today";
}
initTd(td, i);
}
var nextWeek = new Date(year, month + 1, 0).getDay();
if (nextWeek != 6) {
for (i = 1; i < 7 - nextWeek % 6; i++) {
var td = tr.insertCell(tr.cells.length);
initTd(td, i, "after");
}
}
}

//辅助函数,生成特定类型的td
function initTd(td, text, className){
td.innerHTML = text + "";
if (className != "week")
td.onclick = getDate;
if (className) {
td.className = className;
if (className == "before")
td.title = (parseInt(document.getElementById("year").innerHTML) - 1 + Math.floor((parseInt(document.getElementById("month").innerHTML) + 10) / 12)) + "-" + ((parseInt(document.getElementById("month").innerHTML) + 10) % 12 + 1) + "-" + text;
else
if (className == "after")
td.title = (parseInt(document.getElementById("year").innerHTML) + Math.floor((parseInt(document.getElementById("month").innerHTML) + 1) / 12)) + "-" + (parseInt(document.getElementById("month").innerHTML) % 12 + 1) + "-" + text;
else
td.title = "星期" + text;
}
else
td.title = document.getElementById("year").innerHTML + "-" + document.getElementById("month").innerHTML + "-" + text;
}

//创建特定类型的span
function createSpan(innerHTML, title, idName, className, fun){
span = document.createElement("span");
span.innerHTML = innerHTML;
if (title != null && title != "undefined") {
span.title = title;
}
if (idName != null && idName != "undefined")
span.id = idName;
if (className != null && className != "undefined")
span.className = className;
if (fun != null && fun != "undefined") {
span.onclick = fun;
}
return span;
}

//上一年  按钮<<函数
function lastYear(){
var year = parseInt(document.getElementById("year").innerHTML) - 1;
var month = parseInt(document.getElementById("month").innerHTML) - 1;
initDate(new Date(year, month));
}

//上一月  按钮<函数
function lastMonth(){
var year = parseInt(document.getElementById("year").innerHTML);
var month = parseInt(document.getElementById("month").innerHTML) - 2;
initDate(new Date(year, month));
}

//下一年  按钮>>函数
function nextYear(){
var year = parseInt(document.getElementById("year").innerHTML) + 1;
var month = parseInt(document.getElementById("month").innerHTML) - 1;
initDate(new Date(year, month));
}

//下一月  按钮>函数
function nextMonth(){
var year = parseInt(document.getElementById("year").innerHTML);
var month = parseInt(document.getElementById("month").innerHTML);
initDate(new Date(year, month));
}

//选择月份 月份控件函数
function selectMonth(){
if (document.getElementById("selYear"))
document.getElementById("selYear").style.display = "none";
var cal = document.getElementById("calendar");
var span = document.getElementById("selMonth");
if (span == null) {
span = document.createElement("span");
document.body.appendChild(span);
span.id = "selMonth";
span.style.position = "absolute";

for (var i = 1; i < 13; i++) {
span.appendChild(createSpan(i, i + "月", null, null, getMonth));
}
}
else {
span.style.display = "";
}
var x = this.offsetLeft;
var y = this.offsetTop;
var tt = this;
while (tt = tt.offsetParent) {
y += tt.offsetTop;
x += tt.offsetLeft;
}
span.style.left = (x + 1) + "px";
span.style.top = (y + 1) + "px";
}

//选择年份 年份控件函数
function selectYear(){
if (document.getElementById("selMonth"))
document.getElementById("selMonth").style.display = "none";
var span = document.getElementById("selYear");
if (span == null) {
span = document.createElement("span");
document.body.appendChild(span);
span.id = "selYear";
span.style.position = "absolute";

var childSpan = document.createElement("span");
childSpan.className = "preYear";
childSpan.onmouseover = function(){
minus = setInterval(function(){
changeSel(-1);
}, 100);
}
childSpan.onmouseout = function(){
clearInterval(minus);
}
span.appendChild(childSpan);

for (var i = 0; i < 9; i++) {
span.appendChild(createSpan("", null, null, "yearChild", getYear));
}
childSpan = document.createElement("span");
childSpan.className = "afterYear";
childSpan.onmouseover = function(){
add = setInterval(function(){
changeSel(1);
}, 100);
}
childSpan.onmouseout = function(){
clearInterval(add);
}
span.appendChild(childSpan);
}
else {
span.style.display = "";
}
var cal = document.getElementById("calendar");
var x = this.offsetLeft;
var y = this.offsetTop;
var tt = this;
while (tt = tt.offsetParent) {
y += tt.offsetTop;
x += tt.offsetLeft;
}
span.style.left = (x + 1) + "px";
span.style.top = (y + 1) + "px";
var year = parseInt(this.innerHTML) - 5;
for (var i = 1; i < span.children.length - 1; i++) {
span.children[i].innerHTML = year + i;
span.children[i].title = (year + i) + "年";
}
}

//选取月份
function getMonth(){
document.getElementById("month").innerHTML = this.innerHTML;
this.parentNode.style.display = "none";
initDate();
}

//选取年份
function getYear(){
document.getElementById("year").innerHTML = this.innerHTML;
this.parentNode.style.display = "none";
initDate();
}

//选取年份控件更改选项函数
function changeSel(param){
var sel = document.getElementById("selYear");
var firstYear = parseInt(sel.children[1].innerHTML) + param - 1;
for (var i = 1; i < sel.children.length - 1; i++) {
sel.children[i].innerHTML = firstYear + i;
sel.children[i].title = (firstYear + i) + "年";
}
}

//输入时间函数
function inputTime(ori, num){
var cal = document.getElementById("calendar");
var input = document.getElementById("inputTime");
if (input == null) {
input = document.createElement("input");
input.id = "inputTime";
input.style.position = "absolute";
}
else {
input.style.display = "";
}
var x = ori.offsetLeft;
var y = ori.offsetTop;
var tt = ori;
while (tt = tt.offsetParent) {
y += tt.offsetTop;
x += tt.offsetLeft;
}
input.style.left = (x + 3) + "px";
input.style.top = (y + 2) + "px";
input.value = ori.innerHTML;
input.onfocus = function(){
this.select();
}
var down = false;
input.onkeydown = function(event){
if (event.keyCode == 13) {
input.blur();
}else{
down = true;
}
}
input.onkeyup = function(){
if(down&&this.value.length >= 2){
this.blur();
if(ori.nextSibling){
if(ori.style.visibility == "visible")
ori.nextSibling.nextSibling.click();
}
}
}
input.onblur = function(){
this.style.display = "none";
ori.style.visibility = "visible";
var value = this.value;
if (value == "")
return;
var re = /^\d{1,2}$/;
if (!re.exec(value)) {
return;
}
var numValue = parseInt(value);
if (num == 1) {
if (numValue < 0 || numValue > 23)
numValue = 0;
}
else {
if (numValue < 0 || numValue > 59)
numValue = 0;
}
value = "00" + numValue;
ori.innerHTML = value.substr(value.length - 2);
}
ori.style.visibility = "hidden";
document.body.appendChild(input);
input.focus();
}

//获取所选日期时间 关闭日历
function getDate(){
var value = this.title;
if (document.getElementById("selTime").checked) {
value += (" " + document.getElementById("hour").innerHTML + ":" + document.getElementById("min").innerHTML + ":" + document.getElementById("sec").innerHTML);
}
result.value = value;
close();
}

//重新设置日历日期时间(根据传入的日期时间字符串设置)
function resetDate(){
if (result.value != "") {
var re = /^\d{4}-\d{1,2}-\d{1,2}$|^\d{4}-\d{1,2}-\d{1,2}\W\d{2}:\d{2}:\d{2}/;
if (re.exec(result.value)) {
var value = result.value.split(" ");
if (value.length == 2) {
var time = value[1].split(":");
document.getElementById("time").style.visibility = "visible";
document.getElementById("selTime").checked = true;
document.getElementById("hour").innerHTML = time[0];
document.getElementById("min").innerHTML = time[1];
document.getElementById("sec").innerHTML = time[2];
}
else {
document.getElementById("time").style.visibility = "hidden";
document.getElementById("selTime").checked = false;
}
var dateNum = value[0].split("-");
var year = parseInt(dateNum[0]);
var month = parseInt(dateNum[1]);
var day = parseInt(dateNum[2]);
initDate(new Date(year, month - 1, day), day);
}
else {
initDate(new Date());
}
}
else {
initDate(new Date());
}
}

//关闭日历
function close(){
document.getElementById("calendar").style.display = "none";
if (document.getElementById("selYear"))
document.getElementById("selYear").style.display = "none";
if (document.getElementById("selMonth"))
document.getElementById("selMonth").style.display = "none";
}

//创建日历控件
function createCalendar(){
if (arguments.length == 0) {
alert("There is no arguments, the calendar initialize failed!");
return;
}
result = arguments[0];
var x = arguments[0].offsetLeft;
var y = arguments[0].offsetTop + arguments[0].offsetHeight;
var tt = result;
while (tt = tt.offsetParent) {
y += tt.offsetTop;
x += tt.offsetLeft;
}
if (document.getElementById("calendar")) {
var calendar = document.getElementById("calendar");
calendar.style.display = "block";
calendar.style.position = "absolute";
calendar.style.left = x + "px";
calendar.style.top = y + "px";
resetDate();
return;
}
var calendar = document.createElement("table");

calendar.id = "calendar";
calendar.style.position = "absolute";
calendar.style.left = x + "px";
calendar.style.top = y + "px";
var tr = calendar.insertRow(calendar.rows.length);
var td = tr.insertCell(tr.cells.length);

var span = document.createElement("span");
span.className = "left";
span.appendChild(createSpan("<<", "上一年", null, "btn", lastYear));
span.appendChild(createSpan("<", "上一月", null, "btn", lastMonth));
td.appendChild(span);

td = tr.insertCell(tr.cells.length);
td.colSpan = 2;
span = document.createElement("span");
span.appendChild(createSpan("", "年份", "year", null, selectYear));
span.appendChild(createSpan("年"));
span.appendChild(createSpan("", "月份", "month", null, selectMonth));
span.appendChild(createSpan("月"));
td.appendChild(span);

td = tr.insertCell(tr.cells.length);
span = document.createElement("span");
span.className = "right";
span.appendChild(createSpan(">", "下一月", null, "btn", nextMonth));
span.appendChild(createSpan(">>", "下一年", null, "btn", nextYear));
td.appendChild(span);

tr = calendar.insertRow(calendar.rows.length);
td = tr.insertCell(tr.cells.length);
td.colSpan = 4;
ntable = document.createElement("table");
ntable.id = "date";
td.appendChild(ntable);

tr = calendar.insertRow(calendar.rows.length);
tr.className = "bottom";
td = tr.insertCell(tr.cells.length);
td.appendChild(createSpan("关闭", "关闭", null, "close", close));

td = tr.insertCell(tr.cells.length);
td.colSpan = 2;
var div = document.createElement("div");
div.id = "time";
div.appendChild(createSpan("00", "时", "hour", null, function(){
inputTime(this, 1)
}));
div.appendChild(createSpan(":"));
div.appendChild(createSpan("00", "分", "min", null, function(){
inputTime(this, 2)
}));
div.appendChild(createSpan(":"));
div.appendChild(createSpan("00", "秒", "sec", null, function(){
inputTime(this, 3)
}));
td.appendChild(div);

td = tr.insertCell(tr.cells.length);
var input = document.createElement("input");
input.type = "checkbox";
input.id = "selTime";
input.title = "选择是否需要时间";
input.onclick = function(){
if (this.checked) {
document.getElementById("time").style.visibility = "visible";
}
else {
document.getElementById("time").style.visibility = "hidden";
}
}
td.appendChild(input);
td.appendChild(createSpan("时间", "选择是否需要时间", null, "selTime", function(){
this.previousSibling.click();
}));
document.onclick = function(){
if (calClose) {
close();
}
else {
calClose = true;
}
}
calendar.onclick = function(){
calClose = false;
}

document.body.appendChild(calendar);
resetDate();
}


最后就是使用了,很简单,看下面的例子就知道了(引入CSS、JS文件或者直接全部放在一个页面里(不建议))。

例:<input onfocus="createCalendar(this)"/>

行了,一点输入框就会弹出日历了。

效果图如下:






                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: