纯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 相关文章推荐
Jquery乱码的一次解决过程 图解教程
Feb 20 Javascript
理清apply(),call()的区别和关系
Aug 14 Javascript
Hallo.js基于jQuery UI所见即所得的Web编辑器
Jan 26 Javascript
浅谈JavaScript 浏览器对象
Jun 03 Javascript
详解vue-cli 构建Vue项目遇到的坑
Aug 30 Javascript
vue params、query传参使用详解
Sep 12 Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
Jan 22 Javascript
修改npm全局安装模式的路径方法
May 15 Javascript
解决vue.js this.$router.push无效的问题
Sep 03 Javascript
详解Vue源码中一些util函数
Apr 24 Javascript
原生js实现碰撞检测
Mar 12 Javascript
使用React-Router实现前端路由鉴权的示例代码
Jul 26 Javascript
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
php递归列出所有文件和目录的代码
2008/09/10 PHP
php for 循环语句使用方法详细说明
2010/05/09 PHP
配置php网页显示各种语法错误
2013/09/23 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
繁简字转换功能
2006/07/19 Javascript
(推荐一个超好的JS函数库)S.Sams Lifexperience ScriptClassLib
2007/04/29 Javascript
使用jscript实现二进制读写脚本代码
2008/06/09 Javascript
javascript各种复制代码收集
2008/09/20 Javascript
jQuery+CSS实现一个侧滑导航菜单代码
2016/05/09 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
解决vue中对象属性改变视图不更新的问题
2018/02/23 Javascript
微信上传视频文件提示(推荐)
2018/11/22 Javascript
js变量声明var使用与不使用的区别详解
2019/01/21 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:EE凭借法力虚空拿下4杀
2017/03/30 DOTA
[01:03:13]VG vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[50:27]OG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/30 DOTA
跟老齐学Python之画圈还不简单吗?
2014/09/20 Python
Python简单实现enum功能的方法
2016/04/25 Python
Python cookbook(数据结构与算法)实现优先级队列的方法示例
2018/02/18 Python
python中不能连接超时的问题及解决方法
2018/06/10 Python
Python cv2 图像自适应灰度直方图均衡化处理方法
2018/12/07 Python
Python异常处理例题整理
2019/07/07 Python
Python 转换RGB颜色值的示例代码
2019/10/13 Python
python 消除 futureWarning问题的解决
2019/12/25 Python
python中sklearn的pipeline模块实例详解
2020/05/21 Python
CSS3制作轮播图的一种方法
2019/11/11 HTML / CSS
萌新的HTML5 入门指南
2020/11/06 HTML / CSS
Rhone官方网站:男士运动服装、健身服装和高级运动服
2019/05/01 全球购物
金融专业大学生自我评价
2014/01/09 职场文书
最常使用的求职信
2014/05/25 职场文书
客服专员岗位职责范本
2015/04/07 职场文书
大学生先进个人主要事迹材料
2015/11/04 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
SQL Server使用PIVOT与unPIVOT实现行列转换
2022/05/25 SQL Server
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL