纯javascript版日历控件


Posted in Javascript onNovember 24, 2016

平时只有下班时间能code,闲来写了个纯javascript版。引用该calendar.js文件,然后给要设置成日历控件的input的id设置成calendar,该input就会变成日历控件。

纯javascript版日历控件

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>日历控件</title>
<script src="js/calendar.js" defer></script>
</head>

<body>
<input id="calendar" type="text" />
</body>
</html>

引用calendar.js时,一定要加defer属性。

calendar.js源码:

// JavaScript Document
var days = new Array("日","一","二","三","四","五","六");//星期
var today = new Date();//当天日期,备用
var month_big = new Array("1","3","5","7","8","10","12"); //包含所有大月的数组
var month_small = new Array("4","6","9","11"); //包含所有小月的数组
var separator = "-";//间隔符 

var calendar = document.getElementById("calendar");
var cal_parent = calendar.parentNode;//获取父元素
var cal_width = ((calendar.clientWidth<150) ? 150 : calendar.clientWidth);//获取input的宽度,如果input宽度小于150,调整为150,150为日历块最小宽度
var cal_height = calendar.clientHeight;//获取input的高度,整数
var cal_X = calendar.offsetLeft;//获取input左边 距父元素的距离,整数
var cal_Y = calendar.offsetTop;//获取input顶部 距父元素的距离,整数

calendar.style.cursor = "pointer";//将input的鼠标设置成小手
calendar.readOnly = "readOnly";//设置input为只读
calendar.onblur = hideCalendar; //当input失去焦点时,隐藏cal_body
calendar.onclick = showCalendar;//点击input时调用showCalendar函数

//取input宽度的七分之一再减一作为方格的边长
var pane_height = cal_width/7 - 1; 

function hideCalendar(){
 var cal_body = document.getElementById("cal_body");
 if(cal_body != undefined){
  cal_body.parentNode.removeChild(cal_body);
 }
}

//显示日历主体
function showCalendar(){
 var cal_body = document.getElementById("cal_body");
 if(cal_body != undefined){
  cal_body.parentNode.removeChild(cal_body);
 }
 else{
  var cal_body = document.createElement("DIV");
  cal_body.id = "cal_body";
  cal_body.style.width = cal_width + "px";
  cal_body.style.height = "auto";
  cal_body.style.overflow = "hidden";
  cal_body.style.position = "absolute";
  cal_body.style.zIndex = "9";
  cal_body.style.left = cal_X + "px";
  cal_body.style.top = (cal_Y + cal_height + 5) + "px";
  cal_body.style.border = "solid 1px #CCCCCC";
  //鼠标移动到cal_body上时,禁用input的onblur事件,防止cal_body因input失去焦点而被隐藏
  cal_body.onmouseover = function(){
   calendar.onblur = undefined;
  }
  //鼠标从cal_body移除时,启用input的onblur事件,并且先让input获得焦点,否则当在cal_body上空白处点击后再移出在其他地方点击时,input因没有焦点而无法触发onblur事件
  cal_body.onmouseout = function(){
   calendar.focus();
   calendar.onblur = hideCalendar;
  }
  cal_parent.appendChild(cal_body);
    
  var line1 = document.createElement("DIV");
  line1.style.width = cal_width + "px";
  line1.style.height = pane_height + "px";
  line1.style.backgroundColor = "#0FF";
  
  var btn1 = document.createElement("DIV");
  btn1.style.width = (cal_width/3 - 3) + "px";
  btn1.style.height = pane_height + "px";
  btn1.style.lineHeight = pane_height + "px";
  btn1.style.textAlign = "center";
  btn1.innerHTML = "<";
  btn1.style.cursor = "pointer";
  btn1.style.cssFloat = "left";
  btn1.onclick = function(){
   if(isValidated()){
    var old_year = parseInt(document.getElementById("input_year").value);
    if(old_year > 1960){
     var year = old_year - 1;
     var month = parseInt(document.getElementById("input_month").value);
     var val = year + separator + month + separator + 1;
     init(val);
    }
   }
  };
  line1.appendChild(btn1);
  
  var input_year = document.createElement("INPUT");
  input_year.id = "input_year";
  input_year.style.width = (cal_width/3) + "px";
  input_year.style.height = "70%";
  input_year.style.cssFloat = "left";
  input_year.style.textAlign = "center";
  input_year.onchange = function(){
   changed();
  };
  line1.appendChild(input_year);
  
  var btn2 = document.createElement("DIV");
  btn2.style.width = (cal_width/3 - 3) + "px";
  btn2.style.height = pane_height + "px";
  btn2.style.lineHeight = pane_height + "px";
  btn2.style.textAlign = "center";
  btn2.innerHTML = ">";
  btn2.style.cursor = "pointer";
  btn2.style.cssFloat = "left";
  btn2.onclick = function(){
   if(isValidated()){
    var old_year = parseInt(document.getElementById("input_year").value);
    if(old_year < 2050){
     var year = old_year + 1;
     var month = parseInt(document.getElementById("input_month").value);
     var val = year + separator + month + separator + 1;
     init(val);
    }
   }
  };
  line1.appendChild(btn2);
  
  var line2 = document.createElement("DIV");
  line2.style.width = cal_width + "px";
  line2.style.height = pane_height + "px";
  line2.style.backgroundColor = "#0FF";
  
  var btn3 = document.createElement("DIV");
  btn3.style.width = (cal_width/3 - 3) + "px";
  btn3.style.height = pane_height + "px";
  btn3.style.lineHeight = pane_height + "px";
  btn3.style.textAlign = "center";
  btn3.innerHTML = "<";
  btn3.style.cursor = "pointer";
  btn3.style.cssFloat = "left";
  btn3.onclick = function(){
   if(isValidated()){
    var old_month = parseInt(document.getElementById("input_month").value)
    if(old_month > 1){
     var year = parseInt(document.getElementById("input_year").value);
     var month = old_month - 1;
     var val = year + separator + month + separator + 1;
     init(val);
    }
    else {
     var year = parseInt(document.getElementById("input_year").value) - 1;
     var month = 12;
     var val = year + separator + month + separator + 1;
     init(val);
    }
   }
  };
  line2.appendChild(btn3);
  
  var input_month = document.createElement("INPUT");
  input_month.id = "input_month";
  input_month.style.width = (cal_width/3) + "px";
  input_month.style.height = "70%";
  input_month.style.cssFloat = "left";
  input_month.style.textAlign = "center";
  input_month.onchange = function(){
   changed();
  };
  line2.appendChild(input_month);
  
  var btn4 = document.createElement("DIV");
  btn4.style.width = (cal_width/3 - 3) + "px";
  btn4.style.height = pane_height + "px";
  btn4.style.lineHeight = pane_height + "px";
  btn4.style.textAlign = "center";
  btn4.innerHTML = ">";
  btn4.style.cursor = "pointer";
  btn4.style.cssFloat = "left";
  btn4.onclick = function(){
   if(isValidated()){
    var old_month = parseInt(document.getElementById("input_month").value)
    if(old_month < 12){
     var year = parseInt(document.getElementById("input_year").value);
     var month = parseInt(document.getElementById("input_month").value) + 1;
     var val = year + separator + month + separator + 1;
     init(val);
    }
    else {
     var year = parseInt(document.getElementById("input_year").value) + 1;
     var month = 1;
     var val = year + separator + month + separator + 1;
     init(val);
    }
   }
  };
  line2.appendChild(btn4);
  
  cal_body.appendChild(line1);
  cal_body.appendChild(line2);
  
  for(var i=0; i < 7; i++){
   var pane = document.createElement("DIV");
   pane.className = "pane";
   pane.style.width = pane_height + "px";
   pane.style.height = pane_height + "px";
   pane.style.lineHeight = pane_height + "px";
   pane.style.textAlign = "center";
   pane.style.cssFloat = "left";
   pane.innerHTML = days[i];
   cal_body.appendChild(pane);
  }  
  init(calendar.value); 
 } 
}

function init(val){
 clearPane();
   
 var cal_body = document.getElementById("cal_body");
 var temp_date;
 var year;
 var month;
 var date;
 
 if(val == ""){
  temp_date = today;
  calendar.value = today.toFormatString(separator);
 }
 else{
  year = val.year();
  month = val.month(separator);
  date = val.date(separator);
  temp_date = new Date(year,month,date); 
 }
  
 year = temp_date.getFullYear();
 month = temp_date.getMonth() + 1;
 date = temp_date.getDate();
 temp_date.setDate(1);
 
 var start = temp_date.getDay() + 7;
 var end;
 
 if(array_contain(month_big, month)){
  end = start + 31;
 }
 else if(array_contain(month_small, month)){
  end = start + 30;
 }
 else{
  if(isLeapYear(year)){
   end = start + 29;
  }
  else{
   end = start + 28;
  }
 }
 
 for(var i = 7; i < start; i++){
  var pane = document.createElement("DIV");
  pane.className = "pane";
  pane.style.width = pane_height + "px";
  pane.style.height = pane_height + "px";
  pane.style.lineHeight = pane_height + "px";
  pane.style.textAlign = "center";
  pane.style.cssFloat = "left";
  cal_body.appendChild(pane);
 }
 
 for(var i = start; i < end; i++){  
  var pane = document.createElement("DIV");
  pane.className = "pane";
  pane.style.width = pane_height + "px";
  pane.style.height = pane_height + "px";
  pane.style.lineHeight = pane_height + "px";
  pane.style.textAlign = "center";
  pane.style.cssFloat = "left";
  pane.innerHTML = i - start + 1;
  pane.style.cursor = "pointer";
  pane.onmouseover = function(){
   this.style.backgroundColor = '#0FF';
  }
  if(date == (i - start + 1))
   pane.style.backgroundColor = '#0FF';
  else{
   pane.onmouseout = function(){
    this.style.backgroundColor = '';
   }
  }
  pane.onclick = function(){
   calendar.value = year + separator + month + separator + this.innerHTML;
   cal_body.parentNode.removeChild(cal_body);  
  }
  cal_body.appendChild(pane);
  
  document.getElementById("input_year").value = year;
  document.getElementById("input_month").value = month;
 }
}

//格式化输出
Date.prototype.toFormatString = function(separator){
 var result = this.getFullYear() + separator + (this.getMonth() + 1) + separator + this.getDate();
 return result;
};

//从格式化字符串中获取年份
String.prototype.year = function(){
 var str = this.substring(0,4);
 return str;
};

//从格式化字符串中获取月份
String.prototype.month = function(separator){
 var start = this.indexOf(separator) + 1;
 var end = this.lastIndexOf(separator);
 return parseInt(this.substring(start, end)) - 1;
};

//从格式化字符串中获取日期
String.prototype.date = function(separator){
 var start = this.lastIndexOf(separator) + 1;
 return this.substring(start);
};

//判断数组array中是否包含元素obj的函数,包含则返回true,不包含则返回false
function array_contain(array, obj){
 for (var i = 0; i < array.length; i++){
  if (array[i] == obj)
   return true;
 }
 return false;
}

//判断年份year是否为闰年,是闰年则返回true,否则返回false
function isLeapYear(year){
 var a = year % 4;
 var b = year % 100;
 var c = year % 400;
 if( ( (a == 0) && (b != 0) ) || (c == 0) ){
  return true;
 }
 return false;
}

//清除方格
function clearPane(){
 var limit = document.getElementsByClassName("pane").length;
 for(var i=7; i < limit; i++){
  var pane = document.getElementsByClassName("pane").item(7);
  pane.parentNode.removeChild(pane);
 }
}

//判断输入是否合法
function isValidated(){
 var year = document.getElementById("input_year").value;
 var month = document.getElementById("input_month").value;
 if(isNaN(year) || isNaN(month)){
  alert("请输入正确的年份/月份");
  return false;
 }
 else{
  if(year%1 != 0 || month%1 != 0){
   alert("请输入正确的年份/月份");
   return false;
  }
  else{
   year = parseInt(year);
   if(year < 1960 || year > 2050){
    alert("请输入1960~2050之间的年份!");
    return false;
   }
   else if(month < 1 || month >12){
    alert("请输入正确的月份!");
    return false;
   }
   else{
    return true;
   }
  }
 }
}

//年份月份发生变化时处理函数
function changed(){
 if(isValidated()){
  var year = document.getElementById("input_year").value;
  var month = document.getElementById("input_month").value;
  var val = year + separator + month + separator + 1;
  init(val);
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在IE模态窗口中自由查看HTML源码的方法
Mar 08 Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
May 25 Javascript
javascript阻止scroll事件多次执行的思路及实现
Nov 08 Javascript
深入学习AngularJS中数据的双向绑定机制
Mar 04 Javascript
javaScript事件学习小结(四)event的公共成员(属性和方法)
Jun 09 Javascript
JavaScript易错知识点整理
Dec 05 Javascript
jQuery中 bind的用法简单介绍
Feb 13 Javascript
Vue2.0使用过程常见的一些问题总结学习
Apr 10 Javascript
详解如何使用PM2将Node.js的集群变得更加容易
Nov 15 Javascript
微信小程序使用Promise简化回调
Feb 06 Javascript
微信小程序实现动态获取元素宽高的方法分析
Dec 10 Javascript
Jquery获取radio选中值实例总结
Jan 17 jQuery
js通过classname来获取元素的方法
Nov 24 #Javascript
jQuery实现checkbox列表的全选、反选功能
Nov 24 #Javascript
jQuery Dialog 打开时自动聚焦的解决方法(两种方法)
Nov 24 #Javascript
概述javascript在Google IE中的调试技巧
Nov 24 #Javascript
基于Bootstrap和jQuery构建前端分页工具实例代码
Nov 23 #Javascript
Bootstrap复选框和单选按钮美化插件(推荐)
Nov 23 #Javascript
值得分享的Bootstrap Table使用教程
Nov 23 #Javascript
You might like
DC四月将推出百页特刊漫画 纪念小丑诞生80周年
2020/04/09 欧美动漫
IIS7.X配置PHP运行环境小结
2011/06/09 PHP
ThinkPHP3.1新特性之动态设置自动完成及自动验证示例代码
2014/06/23 PHP
PHP PDO fetch 模式各种参数的输出结果一览
2015/01/07 PHP
Zend Framework教程之Bootstrap类用法概述
2016/03/14 PHP
jquery与prototype框架的详细对比
2013/11/21 Javascript
Javascript学习笔记之 函数篇(一) : 函数声明和函数表达式
2014/06/24 Javascript
javascript关于继承的用法汇总
2014/12/20 Javascript
node.js require() 源码解读
2015/12/13 Javascript
Vue 2.0的数据依赖实现原理代码简析
2017/07/10 Javascript
Javascript中的getter和setter初识
2017/08/17 Javascript
dts文件中删除一个node或属性的操作方法
2018/08/05 Javascript
Angular2之二级路由详解
2018/08/31 Javascript
[03:11]DOTA2上海特锦赛小组赛第一日recap精彩回顾
2016/02/28 DOTA
python中的列表推导浅析
2014/04/26 Python
简单介绍Python中的RSS处理
2015/04/13 Python
在Python中使用SQLite的简单教程
2015/04/29 Python
Python求两个文本文件以行为单位的交集、并集与差集的方法
2015/06/17 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
python2和python3的输入和输出区别介绍
2018/11/20 Python
Opencv实现抠图背景图替换功能
2019/05/21 Python
对Python中一维向量和一维向量转置相乘的方法详解
2019/08/26 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
2020/06/03 Python
python3跳出一个循环的实例操作
2020/08/18 Python
纯CSS实现预加载动画效果
2017/09/06 HTML / CSS
CSS3 实现弹跳的小球动画
2020/10/26 HTML / CSS
Lands’ End官网:经典的美国生活方式品牌
2016/08/14 全球购物
计算机工程学院个人求职信
2013/10/05 职场文书
淘宝中秋节活动方案
2014/01/31 职场文书
街道党工委党的群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
挂职锻炼个人总结
2015/03/05 职场文书
高一地理教学工作总结
2015/08/12 职场文书
导游词之河北邯郸
2019/09/12 职场文书
浅谈Python3中datetime不同时区转换介绍与踩坑
2021/08/02 Python
python中redis包操作数据库的教程
2022/04/19 Python
mysql5.5中文乱码问题解决的有用方法
2022/05/30 MySQL