<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<style>
table {display: inline-block;border: 1px solid red;/**HTML5 中 table的cellspacing和cellpadding时被提示该属性已过时或者提示非法属性border-collapse定义为collapse时,他们的边框会重叠在一起,定义为separate时单元格边框之间会有间隙*/border-collapse:collapse;
}
table td {padding: 0;width: 2rem;height: 2rem;text-align: center;box-sizing: border-box;transition: border-radius .5s ease, border-color .5s;overflow-y: hidden;
}
/* 本来最简单的方法是设置overflow:hidden来遮住多余的背景,但是发现行不通 */
.goPrevMonth>span, .goNextMonth>span {display: inline-block;/** 由于原先的箭头太瘪了,需要拉伸 */transform: scale(1,1.5);/** 由于箭头是文字,因此会被选中,需要设置禁止选中,不然很难看 */user-select: none;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;
}
.goPrevMonth:active, .goNextMonth:active {background-color: Bisque;
}
#calendar tr:nth-child(2) {background-color: SkyBlue;
}
.prevMonth, .nextMonth {color: gray;
}
.week {color: Snow;font-weight: bold;
}
.today {border-radius: 50%;color: white;background-color: Coral;font-weight: bold;
}
.today:hover {box-shadow: 0 0 5px red inset , 0 0 3px orange;border-radius: 0%;
}
.currentMonth {/** 如果不设置的话,默认的起始色为黑色 */border-color: transparent;
}
.currentMonth:hover {border: 2px groove lightgray;
}
</style>
<script>
class CalendarRender {constructor (container) {this.container = container;this.dayOfWeek = ["一","二","三","四","五","六","日"];this.today = new Date();//getMonth的月份的参数介于0-11之间this.firstDayOfMonth = new Date(this.today.getFullYear(), this.today.getMonth(), 1);this.update(0);}//前一个月goPrevMonth() {this.update(-1);}//后一个月goNextMonth() {this.update(1);}calc() {this.data = new Array();const isCurrentMonth = this.firstDayOfMonth.getMonth() == this.today.getMonth();const lastDateOfMonth = new Date(this.firstDayOfMonth.getFullYear(), this.firstDayOfMonth.getMonth()+1, 0);const lastDate = lastDateOfMonth.getDate();//星期日的值为0const firstDay = this.firstDayOfMonth.getDay();let prevCount = 0;let prevLastDate = 0;if(firstDay != 1) {const firstDayOfMonthYesterday = new Date(this.firstDayOfMonth.getFullYear(), this.firstDayOfMonth.getMonth(), 0);prevLastDate = firstDayOfMonthYesterday.getDate();if(firstDay == 0) {prevCount = 6;} else {prevCount = firstDay - 1;}}let n = 0;let m = 0;for(let i=0; i<5; i++) {for(let j=0; j<7; j++) {if(i == 0 && prevCount > j) {this.data.push([prevLastDate - prevCount + 1 + j, -1]);} else if(n == lastDate) {m++;this.data.push([m,1]);} else {n++;if(isCurrentMonth && n == this.today.getDate()) {this.data.push([n,0xFF]);} else {this.data.push([n,0]);}}}}}render() {this.container.innerHTML = "";let index = 0, tr, td;const table = document.createElement("table");tr = document.createElement("tr");const lttd = document.createElement("td");const gttd = document.createElement("td");td = document.createElement("td");//getMonth的月份的参数介于0-11之间td.textContent = this.firstDayOfMonth.getFullYear() + " 年 " + (this.firstDayOfMonth.getMonth()+1) + " 月"//colSpan设置列跨度,rowSpan设置行跨度td.colSpan = 5;lttd.innerHTML = "<span>&lt</span>";gttd.innerHTML = "<span>&gt</span>";lttd.className = "goPrevMonth";gttd.className = "goNextMonth";table.appendChild(tr);tr.appendChild(lttd);tr.appendChild(td);tr.appendChild(gttd);//这么写是错误的,因为click函数中的this不是当前对象,因此可以通过缓存this的办法解决//lttd.onclick = this.goPrevMonth;//gttd.onclick = this.goNextMonth;const that = this;lttd.onclick=()=>{that.goPrevMonth.apply(that)};gttd.onclick=()=>{that.goNextMonth.apply(that)};tr = document.createElement("tr");for(let i=0; i<this.dayOfWeek.length; i++) {td = document.createElement("td");td.innerText = this.dayOfWeek[i];td.className = "week";tr.appendChild(td);}table.appendChild(tr);for(let i=0; i<5; i++) {tr = document.createElement("tr");for(let j=0; j<7; j++) {td = document.createElement("td");const data = this.data[index];td.textContent = data[0];index++;let className;switch(data[1]) {case -1:className = "prevMonth";break;case 0:className = "currentMonth";break;case 1:className = "nextMonth";break;case 0xFF:className = "today";break;}td.className = className;tr.appendChild(td);}table.appendChild(tr);}this.container.appendChild(table);}update(monthDiff) {this.firstDayOfMonth.setMonth(this.firstDayOfMonth.getMonth()+monthDiff);this.calc();this.render();}
}
window.()=>{const calendar = document.getElementById("calendar");const tool = new CalendarRender(calendar);
}
</script>
</head>
<body>
<div id="calendar"></div>
</body>
</html>

JavaScript 日历相关推荐

  1. 精心挑选12款优秀的 JavaScript 日历和时间选择插件

    今天这篇文章向大家分享12款精心挑选的优秀 JavaScript 日历和时间选择插件,都带有详细的使用教程和效果演示.这些插件能够帮助 Web 开发人员更快速的实现各种精美的日历和时间选择效果.同时推 ...

  2. 12款优秀的 JavaScript 日历和时间选择控件

    这些插件能够帮助  Web 开发人员更快速的实现各种精美的日历和时间选择效果. 1. The Coolest Calendar 界面非常漂亮的一款日期选择插件,有详细的使用文档,最新版本 1.5. 点 ...

  3. javascript日历插件

    javascript日历插件 原文:javascript日历插件 javascript日历插件 最近在尝试着写javascript日历插件,所以也到github上看国外人日历源码,或者国内人写的好点的 ...

  4. JavaScript日历(es5版本)

    近期在知乎上看到这么一个帖子,题主说自己JavaScript都学完了,结果老师留的作业还是不会写,就是写一个日历的插件,结果楼下一堆大牛出现了,百度的阿里的纷纷站出来发表自己的看法,有人认为简单,有人 ...

  5. 前端ui组件(1):日程排班—11个优秀JavaScript 日历插件

    日历是我们生活中重要的一部分.在当今世界,人们大多使用网络或移动日历.它们随处可见,包括在各种软件中:预订应用.旅行软件.项目管理.管理面板等. 出于多种原因,用户可能需要在网站上使用日历.用户需要容 ...

  6. Javascript日历

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD& ...

  7. 11个顶级 JavaScript 日历插件

    参考链接:https://mp.weixin.qq.com/s?__biz=MzI3NzIzMDY0NA==&mid=2247487050&idx=1&sn=e1cf66726 ...

  8. JS日历控件优化(增加时分秒)

    JS日历控件优化  在今年7月份时候 写了一篇关于 "JS日历控件" 的文章 , 当时只支持 年月日 的日历控件,现在优化如下:      1. 在原基础上 支持 yyyy-mm- ...

  9. Calendars - 日历插件

    Calendars - 日历插件 1)jQuery Frontier Calendar是一个可灵活定制的月日历jQuery插件,看起来类似于Google Calendar.当在一个日期单元格中有比较多 ...

最新文章

  1. conda Linux系统下的安装与使用
  2. 利用Python延迟初始化提升性能
  3. 数据中心布线系统的整体规划
  4. 将自己写的windows服务加入到windows集群中
  5. 用java判断一个年份是否为闰年_判断闰年还是平年
  6. 终端mysql Operation not permitted错误解决方案
  7. WebMvcConfigurerAdapter过时的替换方法
  8. chapter8.1、面向对象
  9. 逆序对算法c语言,归并排序求逆序对的代码(C语言)
  10. 解决ASP.NET2.0和1.1在同一台电脑上不能并行的问题(转)
  11. Linux 操作命令大全
  12. MapGuide open source开发心得一:简介
  13. (二)VISIO 中间带箭头的弧线怎么画
  14. Powermill数控编程培训,潇洒模具三步教您精通cnc数控编程
  15. python小程序实现 --- 乌龟吃鱼(练习点——面向对象的特性:继承,多态,封装)
  16. 陈强老师公开课笔记1——如何区别中介效应、调节效应与交互效应?
  17. 实践篇(4):Apache jena SPARQL endpoint及推理
  18. acm竞赛java很少,Java多线程在ACM竞赛中的应用
  19. 什么是项目生命周期?如何划分项目阶段?有什么意义?
  20. 用iconv 文件格式转换

热门文章

  1. C语言 经典结论题第一篇
  2. linux查看ipsec命令,Linux 下 IPsec-tools的使用
  3. ps怎么制作流体_怎么用PS制作液化流体渐变海报
  4. 【MySQL】数据库索引原理 | 索引数据结构 | B+Tree
  5. Python 字典的删除
  6. hbase几种查询方式对比
  7. bcc校验c语言实现,Linux BCC(异或校验)计算命令行工具
  8. C语言 define 定义函数 - C语言零基础入门教程
  9. 解决IBGP的水平分割和BGP选路原则
  10. 建华建材“霸王条款”惹争议,采购商反遭诉讼如何维权?