没有完善,以后再做修改:
1、使用方法还可以更简单。
2、onresize事件可以控制在日期类中更好。
3、控制点击在日历外时隐藏日历。
4、多处同时调用的时候,当获取其中一个焦点,另外一个需要隐藏。
5、代码有较多的冗余。
但是还是通过这个demo巩固了一些知识。
在调用该日历时需要导入定义的Calendar.css,修改CSS.export对应的目录即可导入成功。
样式效果预览:
Calendar.css
/* Calendar.css
@author:xuzengqiang
@explain:日历控件css样式
*/
*{margin:0;padding:0;font-family:微软雅黑;}
.calendar{height:200px;width:200px;border:1px solid #AFAFAF;background:#FFFFFF;border-radius:0px 0px 2px 2px;background:#EFEFEF;text-align:center;}
.calendar ul{list-style:none;height:25px;}
.calendar ul li{float:left;font-size:10pt;}
.calendar .cal_head{height:25px;border-bottom:1px solid #AFAFAF;}
.calendar .date_oper{height:25px;background:#CFCFCF;border-bottom:#DFDFDF;box-shadow:inset 0 0 4px #AFAFAF}
.calendar b{width:0px;height:0px;border-bottom:8px solid transparent;border-top:8px solid transparent;display:block;cursor:pointer;margin-top:5px;}
.plus_year, .plus_month{border-right:8px solid #FFFFFF;float:left;margin-left:5px;}
.add_year, .add_month{border-left:8px solid #FFFFFF;float:right;margin-right:5px}
.plus_year {border-right:8px solid #6F6F6F;}
.add_year {border-left:8px solid #6F6F6F;}
.date_oper span{line-height:25px;color:#6F6F6F;font-size:10pt;}
.cal_content table{width:200px;border:1px solid #CFCFCF;border-top:0px;text-align:center;font-size:10pt;border-left:0px;}
.cal_content table .table_head{background:#FFFFFF;}
.cal_content table tr{height:20px;line-height:20px;}
.cal_content table td{border-left:0px;border-top:0px;}
.cal_content table .table_head td{border:0px;border-bottom:1px solid #CFCFCF}
.cal_content .no_use{background:#FFFFFF;color:#AFAFAF}
.cal_oper{height:22px;}
.cal_oper button{width:50px;height:22px;margin-top:2px;background:#FFFFFF;border:1px solid #AFAFAF;font-size:10pt;
border-radius:4px;}
.cal_oper .close_calendar{margin-left:20px;}
调用demo.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<style type="text/css">
*{margin:0;padding:0;font-family:微软雅黑}
#test{height:700px;width:500px;border:5px solid #AFAFAF;border-radius:2px;box-shadow:0px 0px 20px #DFDFDF;
position:absolute;left:50%;margin-left:-250px;top:50%;margin-top:-350px;}
.title{height:40px;background:#CFCFCF;border-bottom:1px solid #AFAFAF;}
.title span{font-size:13pt;line-height:40px;margin-left:3px;color:#3399CC;}
.beginTime{margin-top:30px;margin-left:10px;}
.beginTime input{height:30px;border:1px solid #3399CC;margin-left:5px;width:200px;font-family:微软雅黑;line-height:
30px;border-radius:2px;color:#6F6F6F;}
</style>
</head>
<body>
<div id="test">
<div class="title">
<span>日历控件</span>
</div>
<div class="content">
<div class="beginTime">
开始时间:<input type="text" id="beginTime" /><br/><br/><br/><br/><br/><br/>
结束时间:<input type="text" id="endTime" />
</div>
</div>
</div>
</body>
<script type="text/javascript">
//对象的创建
var Class = {
create:function(){
return function(){
this.initialize.apply(this,arguments);
};
}
};
//DOM对象的操作
var DOM = (function(window) {
var document = window.document,
location = window.location,
event = event || window.event;
return {
// 根据Id查询DOM对象
getObjectById : function() {
if (arguments.length == 1 && typeof arguments[0] == "string") {
return document.getElementById(arguments[0]);
}
},
// target:绑定事件的对象 eventType:事件类型 fn:绑定事件的方法
addEvent : function(target, eventType, fn) { // 事件绑定
if (target.addEventListener) {
target.addEventListener(eventType, fn, false);
} else if (target.attachEvent) {
target.attachEvent("on" + eventType, fn);
} else {
target["on" + eventType] = fn;
}
},
// target:绑定事件的对象 eventType:事件类型 fn:绑定事件的方法
removeEvent : function(target, eventType, fn) { // 移除事件
if (target.removeEventListener) {
target.removeEventListener(eventType, fn, false);
} else if (target.detachEvent) {
target.detachEvent("on" + eventType, fn);
} else {
target["on" + eventType] = false;
}
},
// 取消事件冒泡
stopPropagation : function() {
if (!event)
return;
if (event.stopPropagation) {
event.stopPropagation();
}
event.cancelBubble = true; // IE
},
// 阻止默认行为
preventDefault : function() {
if (!event)
return;
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false; //IE
}
},
//绑定obj到fun中
bind:function(obj,fun){
return function(){
fun.apply(obj,arguments);
};
}
};
})(window);
//CSS操作
var CSS = (function(window){
var document = window.document,
head = document.head || document.getElementsByTagName("head")[0],
node = document.createElement("link");
node.rel = "stylesheet";
node.type = "text/css";
function load(url,callback) {
if(typeof url != "string" || url == null || url == '') {
return ;
}
if(node.readyState) {
node.onreadystatechange = function(){
if(node.readyState == "loaded" || node.readyState == "complete") {
node.onreadystatechange = null;
callback();
}
};
} else {
node.onload = function(){
callback();
};
}
node.href = url;
head.appendChild(node);
}
return {
//导入css
export:function(url,callback){
load(url,callback);
}
};
})(window);
//DATE操作
var DATE=(function(window){
var upper = ['日','一','二','三','四','五','六'];
return {
convert:function(num){
return upper[num];
}
}
})(window);
//使得除IE之外的元素也可以使用currentStyle获取样式值
if(! document.all){
HTMLElement.prototype.__defineGetter__("currentStyle", function () {
return this.ownerDocument.defaultView.getComputedStyle(this, null);
});
}
/**
*obj.offsetTop:相对于计算机顶端的坐标,没有加上边框,offsetLeft
*obj.clientWidth:对象本身的宽度,不包括边框
*event.clientX 相对文档的水平座标
*event.offsetX 相对容器的水平坐标
*边框高度:IE下可以使用obj.currentStyle.borderWidth获取边框高度
*火狐下面只能使用getComputedStyle方法
*/
function position(target){
var pos = {"left":0,"top":0},
leftWidth = parseInt(target.currentStyle.borderLeftWidth),
height = parseInt(target.currentStyle.height)+parseInt(target.currentStyle.borderTopWidth)
+parseInt(target.currentStyle.borderBottomWidth);
if(target.offsetParent) {
pos.left = target.offsetLeft;
pos.top = target.offsetTop;
target = target.offsetParent;
while(target.offsetParent) { //需要考虑有边框的情况
pos.left += target.offsetLeft+parseInt(target.currentStyle.borderLeftWidth);
pos.top += target.offsetTop+parseInt(target.currentStyle.borderTopWidth);
target = target.offsetParent;
}
}
return {x:pos.left,
y:pos.top,
dateX:pos.left+leftWidth,
dateY:pos.top+height
};
}
var Calendar = Class.create();
Calendar.prototype = {
initialize : function(target, idName, callback) {
this.target = DOM.getObjectById(target);
this.target.readOnly="readonly";
this.name = idName;
this.dateInit();
this.styleInit();
this.loadCalendar();
DOM.addEvent(this.target,"focus",DOM.bind(this,this.showCalendar));
//DOM.addEvent(this.target,"blur",DOM.bind(this,this.closeCalendar));
},
//date所需数据初始化
dateInit : function(){
var date = new Date();
this.day = [31,0,31,30,31,30,31,31,30,31,30,31]; //每个月的天数,需要考虑闰年2月份天数不同
this.currentYear = date.getFullYear(); //初始化为当前年份
this.currentMonth = date.getMonth(); //初始化为当前月份
},
// 是否为闰年
leadYear : function(year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
},
//2月份天数设置
februarySet:function(year){
return this.leadYear(year)?28:29;
},
// 样式初始化
styleInit : function() {
var document = window.document,
content = document.createElement("div"),
body = document.body || document.getElementsByTagName("body")[0];
content.setAttribute("id",this.name);
content.setAttribute("class","calendar");
content.style.position = "absolute";
content.style.zIndex="99";
content.style.display="none";
this.calendar = content;
content.style.left=position(this.target).dateX+"px";
content.style.top=position(this.target).dateY+"px";
body.appendChild(content);
content.innerHTML="<div class='cal_head'></div><div class='cal_content'></div><div class='cal_oper'></div>";
contentNode = content.childNodes;
for(var i=0,maxLen=contentNode.length;i<maxLen;i++) {
var child = contentNode[i];
if(child.className == "cal_head") {
child.innerHTML="<div class='date_oper'>"
+"<b class='plus_year' title='上一年'></b><b class='plus_month' title='上一月'></b>"
+"<span><span class='cur_year'>"+this.currentYear+"</span>年</span>"
+"<span><span class='cur_month'>"+(this.currentMonth+1)+"</span>月</span>"
+"<b class='add_year' title='下一年'></b><b class='add_month' title='下一月'></b>"
+"</div>";
}
if(child.className == 'cal_content') {
this.dateList = document.createElement("table");
this.dateList.border="1";
this.dateList.cellSpacing="0";
this.dateList.cellPadding="0";
child.appendChild(this.dateList);
}
if(child.className == "cal_oper") {
var ensure = document.createElement("button"),
cancel = document.createElement("button");
ensure.className="select_date";
cancel.className="close_calendar";
ensure.innerHTML="确定";
cancel.innerHTML="取消";
child.appendChild(ensure);
child.appendChild(cancel);
DOM.addEvent(ensure,"click",DOM.bind(this,this.closeCalendar));
DOM.addEvent(cancel,"click",DOM.bind(this,this.clear));
}
}
//时间操作
var pYear = this.getElement("b","plus_year")[0];
DOM.addEvent(pYear,"click",DOM.bind(this,this.plusYear));
var aYear = this.getElement("b","add_year")[0];
DOM.addEvent(aYear,"click",DOM.bind(this,this.addYear));
var pMonth = this.getElement("b","plus_month")[0];
DOM.addEvent(pMonth,"click",DOM.bind(this,this.plusMonth));
var aMonth = this.getElement("b","add_month")[0];
DOM.addEvent(aMonth,"click",DOM.bind(this,this.addMonth));
},
//加载日历
loadCalendar:function(){
this.day[1]=this.februarySet(this.currentYear); //初始化二月份
//初始化日期为当前年当前月的1号,获取1号对应的星期
var oneWeek=new Date(this.currentYear,this.currentMonth,1).getDay();
if(oneWeek == 0) oneWeek = 7;
this.dateList.innerHTML=""; //清空日期列表
var row , cell , count = 31 , start = 1, end = 1;
for(var i=0;i<7;i++) {
row = document.createElement("tr");
for(var j=1;j<=7;j++) {
if(i==0) { //设置时间列表
row.className = "table_head";
cell = document.createElement("td");
cell.appendChild(document.createTextNode(DATE.convert(j-1)));
} else {
cell = document.createElement("td");
if((i-1)*7+j<=oneWeek) { //从第二行开始设置值
cell.appendChild(document.createTextNode(count--));
cell.className = "no_use";
} else if( (i-1)*7+j <= this.day[this.currentMonth]+oneWeek ){
var result = (start < 10)?"0"+start:start;
start++;
cell.appendChild(document.createTextNode(result));
cell.style.cursor="pointer";
DOM.addEvent(cell,"mouseover",this.over); //事件绑定
DOM.addEvent(cell,"mouseout",this.out);
DOM.addEvent(cell,"click",DOM.bind(this,this.selectDate));
} else {
var result = (end < 10)?"0"+end:end;
end++;
cell.appendChild(document.createTextNode(result));
cell.className = "no_use";
}
if(j==7) { //去除最右侧td右边框
cell.style.borderRight = "0px";
}
}
row.appendChild(cell);
}
this.dateList.appendChild(row);
}
},
//找到该日历下的对应元素,elementName:元素名称如:b,span;className:对应的className
getElement:function(elementName,className){
var operList = DOM.getObjectById(this.name).getElementsByTagName(elementName),
elements = new Array();
for(var i=0,maxLen = operList.length;i<maxLen;i++){
var classNames=operList[i].className.split(' ');
//alert(classNames);
for(var j=0,len=classNames.length;j<len;j++) {
if(className==classNames[j]) {
elements.push(operList[i]);
break;
}
}
}
return elements;
},
//当获取焦点时显示日历
showCalendar:function() {
DOM.getObjectById(this.name).style.display="block";
},
//当失去焦点关闭日历
closeCalendar:function() {
DOM.getObjectById(this.name).style.display="none";
},
clear:function(){
DOM.getObjectById(this.name).style.display="none";
this.target.value="";
},
//新增年份
addYear:function(){
this.getCurrentTime();
this.currentYear = this.currentYear + 1;
this.editCurrentTime();
this.loadCalendar();
},
//减少年份
plusYear:function(){
this.getCurrentTime();
this.currentYear = this.currentYear - 1;
this.editCurrentTime();
this.loadCalendar();
},
//增加月份
addMonth:function() {
this.getCurrentTime();
if(this.currentMonth==11){
this.currentMonth=0;
this.currentYear=this.currentYear+1;
} else {
this.currentMonth=this.currentMonth+1;
}
this.editCurrentTime();
this.loadCalendar();
},
//减少月份
plusMonth:function() {
this.getCurrentTime();
if(this.currentMonth==0) {
this.currentMonth=11;
this.currentYear=this.currentYear-1;
} else {
this.currentMonth=this.currentMonth-1;
}
this.editCurrentTime();
this.loadCalendar();
},
getCurrentTime:function() {
this.currentYear = parseInt(this.getElement("span","cur_year")[0].innerHTML);
this.currentMonth = parseInt(this.getElement("span","cur_month")[0].innerHTML) - 1;
},
editCurrentTime:function(){
this.getElement("span","cur_year")[0].innerHTML=this.currentYear;
this.getElement("span","cur_month")[0].innerHTML=this.currentMonth+1;
},
over:function(){
this.style.backgroundColor = "#3399CC";
this.style.color = "#FFFFFF";
},
out:function(){
this.style.backgroundColor = "#EFEFEF";
this.style.color = "#000000";
},
selectDate:function(event){ //选中日期
var event = event || window.event,
obj = event.srcElement || event.target;
this.target.value=this.currentYear+"-"+this.currentMonth+"-"+obj.innerHTML;
}
};
//加载需要导入的css路径,相对路径
CSS.export("Calendar.css",function(){
//当日历CSS加载完成后才调用Calendar进行日历操作
var id="calendar",
target="beginTime",
beginTime = new Calendar(target,id);
var id2="csfe",
target2="endTime",
endTime = new Calendar(target2,id2);
window.οnresize=function(){
DOM.getObjectById(id).style.left=position(DOM.getObjectById(target)).dateX+"px";
DOM.getObjectById(id).style.top=position(DOM.getObjectById(target)).dateY+"px";
DOM.getObjectById(id2).style.left=position(DOM.getObjectById(target2)).dateX+"px";
DOM.getObjectById(id2).style.top=position(DOM.getObjectById(target2)).dateY+"px";
}
});
</script>
</html>