纯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 相关文章推荐
10个实用的脚本代码工具
May 04 Javascript
jQuery使用元素属性attr赋值详解
Feb 27 Javascript
基于JavaScript怎么实现让歌词滚动播放
Nov 03 Javascript
JavaScript头像上传插件源码分享
Mar 29 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
Nov 21 Javascript
手机端js和html5刮刮卡效果
Sep 29 Javascript
Vue.js展示AJAX数据简单示例讲解
Mar 29 Javascript
JS请求servlet功能示例
Jun 01 Javascript
VUE元素的隐藏和显示(v-show指令)
Jun 23 Javascript
JS实现闭包中的沙箱模式示例
Sep 07 Javascript
vue中多路由表头吸顶实现的几种布局方式
Apr 12 Javascript
JS实现前端动态分页码代码实例
Jun 02 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
如何限制访问者的ip(PHPBB的代码)
2006/10/09 PHP
php处理斐波那契数列非递归方法
2012/02/04 PHP
php中apc缓存使用示例
2013/12/25 PHP
JS支持带x身份证号码验证函数
2008/08/10 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
js实现点击文本框显示日期选择器特效代码分享
2020/05/21 Javascript
js文本框走动跑马灯效果代码分享
2015/08/25 Javascript
完美实现八种js焦点轮播图(上篇)
2016/07/18 Javascript
关于JS中二维数组的声明方法
2016/09/24 Javascript
vue-cli 默认路由再子路由选中下的选中状态问题及解决代码
2018/09/06 Javascript
JavaScript函数的4种调用方法实例分析
2019/03/05 Javascript
vue组件间通信六种方式(总结篇)
2019/05/15 Javascript
vue tab切换,解决echartst图表宽度只有100px的问题
2020/07/19 Javascript
基于Python中单例模式的几种实现方式及优化详解
2018/01/09 Python
Python 获取div标签中的文字实例
2018/12/20 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
2019/02/16 Python
简单了解python的break、continue、pass
2019/07/08 Python
Python学习笔记之错误和异常及访问错误消息详解
2019/08/08 Python
Python数据处理篇之Sympy系列(五)---解方程
2019/10/12 Python
python读取当前目录下的CSV文件数据
2020/03/11 Python
利用django model save方法对未更改的字段依然进行了保存
2020/03/28 Python
Django 解决由save方法引发的错误
2020/05/21 Python
Python如何对XML 解析
2020/06/28 Python
Pycharm github配置实现过程图解
2020/10/13 Python
python 实现全球IP归属地查询工具
2020/12/18 Python
以特惠价提供在线奢侈品购物:FRMODA.com
2018/01/25 全球购物
英国空调、除湿机和通风设备排名第一:Air Con Centre
2019/02/25 全球购物
adidas泰国官网:adidas TH
2020/07/11 全球购物
计算机专业推荐信范文
2013/11/27 职场文书
村党的群众路线教育实践活动总结材料
2014/10/31 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
2015年团委副书记工作总结
2015/07/23 职场文书
Python 用户输入和while循环的操作
2021/05/23 Python
python引入其他文件夹下的py文件具体方法
2021/05/23 Python
ubuntu如何搭建vsftpd服务器
2022/12/24 Servers