纯JS 日历插件

没有完善,以后再做修改:

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>




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值