当我们需要在页面中显示某月的事项,或是选择某一段日期时,常常要使用到日历组件。这一组件同样有着许多现成的类库,然而亲自动手开发一个日历,从中了解其实现原理也是非常必要的。在本例中我们就将制作一款非常经典的日历组件。

更多精彩内容欢迎访问我的个人博客皮皮猪:http://www.zhsh666.xyz或者http://www.zh66.club期待您的光临哦!我是皮皮猪,感谢各位光临,能为您排忧解难小站深感荣幸!祝您生活愉快!

1. 创建DOM代码

本例的HTML代码如下:

<div class="calendar"><div class="title"><h1 class="green" id="calendar-title">Month</h1><h2 class="green small" id="calendar-year">Year</h2><a href="" id="prev">Prev Month</a><a href="" id="next">Next Month</a></div><div class="body"><div class="lightgrey body-list"><ul><li>MON</li><li>TUE</li><li>WED</li><li>THU</li><li>FRI</li><li>SAT</li><li>SUN</li></ul></div><div class="darkgrey body-list"><ul id="days"></ul></div></div>
</div>

由以上代码可见,日历的最外层是一个类名为calendar的div元素,其内部包含了两大部分,分别是日历顶部的标题区域,其类名为title,以及其下方的日期区域,其类名为body。

在title中包含了当前所选日期的月份、年份,其id分别为calendar-title和calendar-year,此外该元素还包括了prev和next两个按钮,分别用于切换选择上一月和下一月。

在body中首先包含了一个周一到周日的英文表头,它们放在一个ul元素中。在表头之后是另一个div元素,用于显示日历主体。其中,日历所选月份的每一天都将显示在该元素内部的days列表中。

2. CSS样式

本例中大部分的基础CSS样式省略介绍,在此仅介绍其中的body-list类。该类用于设置日历表头和日期数据的栅格显示。我们将整个ul元素的宽度设置为100%,并将其除以7,就可以得到每一个li元素的宽度,即14.28%,将这些元素左浮动显示,就可以得到日期的7列显示,样式代码如下:

.calendar{width:450px;height:350px;background:#fff;box-shadow:0px 1px 1px rgba(0,0,0,0.1);
}
.body-list ul{width:100%;font-family:arial;font-weight:bold;font-size:14px;
}
.body-list ul li{width:14.28%;height:36px;line-height:36px;list-style-type:none;display:block;box-sizing:border-box;float:left;text-align:center;
}

此外,我们为今天、今天之前及今天之后的日期分别创建了不同的类。其中,用浅灰色来显示过去的日期,深灰色来显示将来的日期,日期当天则使用浅绿色背景、绿色文字加以显示,样式代码如下:

.lightgrey{color:#a8a8a8; /*浅灰色*/
}
.darkgrey{color:#565656; /*深灰色*/
}
.green{color:#6ac13c; /*绿色*/
}
.greenbox{border:1px solid #6ac13c;background:#e9f8df; /*浅绿色背景*/
}

日历组件的初始显示效果如下图所示。

3. JavaScript生成日历

接着使用JavaScript来动态生成日历信息。首先,我们要做一些前期的准备工作。由于闰年和非闰年的二月天数是不一样的,在此我们为这两种年份分别创建数组,以便于获取每个月的天数,同时为每个月份的英文名创建相应的数组变量,代码如下:

var month_olympic = [31,29,31,30,31,30,31,31,30,31,30,31];
var month_normal = [31,28,31,30,31,30,31,31,30,31,30,31];
var month_name = ["January","Febrary","March","April","May","June","July","Auguest","September","October","November","December"];

然后,为页面中的各种元素创建变量,以便于后续的引用,代码如下:

var holder = document.getElementById("days");
var prev = document.getElementById("prev");
var next = document.getElementById("next");
var ctitle = document.getElementById("calendar-title");
var cyear = document.getElementById("calendar-year");

创建一个Date对象来获取当前的日期时间,并通过getFullYear()方法来获取当前年份,getMonth()方法来获取月份,getDate()方法来获取当前日期。代码如下:

var my_date = new Date();
var my_year = my_date.getFullYear();
var my_month = my_date.getMonth();
var my_day = my_date.getDate();

我们要实现日历的排布,最关键的问题是要知道某一月第一天究竟是星期几,然后才可以根据当月的天数来依次排列其后的日期。在此,专门为该功能创建一个函数,代码如下:

//获取某年某月第一天是星期几
function dayStart(month, year) {var tmpDate = new Date(year, month, 1);return (tmpDate.getDay());
}

此外,我们也创建一个相应的函数来获取某月的总天数,代码如下:

//计算某年是不是闰年,通过求年份除以4的余数即可
function daysMonth(month, year) {var tmp = year % 4;if (tmp == 0) {return (month_olympic[month]);} else {return (month_normal[month]);}
}

然后,创建一个refreshDate函数来生成月份显示,代码如下:

function refreshDate(){var str = "";var totalDay = daysMonth(my_month, my_year); //获取该月总天数var firstDay = dayStart(my_month, my_year); //获取该月第一天是星期几var myclass;for(var i=1; i<firstDay; i++){ str += "<li></li>"; //为起始日之前的日期创建空白节点}for(var i=1; i<=totalDay; i++){if((i<my_day && my_year==my_date.getFullYear() && my_month==my_date.getMonth()) || my_year<my_date.getFullYear() || ( my_year==my_date.getFullYear() && my_month<my_date.getMonth())){ myclass = " class='lightgrey'"; //当该日期在今天之前时,以浅灰色字体显示}else if (i==my_day && my_year==my_date.getFullYear() && my_month==my_date.getMonth()){myclass = " class='green greenbox'"; //当天日期以绿色背景突出显示}else{myclass = " class='darkgrey'"; //当该日期在今天之后时,以深灰字体显示}str += "<li"+myclass+">"+i+"</li>"; //创建日期节点}holder.innerHTML = str; //设置日期显示ctitle.innerHTML = month_name[my_month]; //设置英文月份显示cyear.innerHTML = my_year; //设置年份显示
}
refreshDate(); //执行该函数

测试页面,日历显示效果如下图所示。

4. 添加交互动作

最后,我们为prev和next元素分别创建onclick事件函数,使得每点击一次prev,则将当前月份减去1,并调用refreshDate函数刷新日历显示。当月份数值小于0时,则使年份减去1,并使月份变为11,使日历显示为前一年的12月。next的功能与其恰好相反。代码如下:

prev.onclick = function(e){e.preventDefault();my_month--;if(my_month<0){my_year--;my_month = 11;}refreshDate();
}
next.onclick = function(e){e.preventDefault();my_month++;if(my_month>11){my_year++;my_month = 0;}refreshDate();
}

测试页面,日历中前一月、后一月的切换效果如下图所示。

下载源文件:https://cloud.ecnu.edu.cn/p/DVF08RwQGRi6Aw

最后,希望这篇文章对大家自定义开发页面中的日历组件有所帮助!

转载于:https://www.cnblogs.com/zhsh666/p/11380873.html

HTML+JavaScript自己动手做日历相关推荐

  1. 免费下载Word模板 自己动手做日历

    自从在Word 97里面发现日历制作向导可以制作带农历的日历,就常将心仪MM的照片换到日历中,再用单位仅有的一台EPSON针式打印机打印出来送给MM,--那是很久很久以前的事了. Office 200 ...

  2. 「雕爷学编程」Arduino动手做(29)——DS1302时钟模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  3. 论山寨手机和Android 【8】 自己动手做XP手机,DIY实战指南

    [8] 自己动手做XP手机,DIY实战指南 2010年1月20日,ViewSonic在北京发布了一款真正意义的电脑手机VCP08.根据商家的宣传,VCP08之所以能够被称为真正的电脑手机,是因为&qu ...

  4. 开关面板如何自己印字_如何自己动手做一个智能开关

    现在的智能家居这么火,对于想自己动手的小伙伴们来说,都想自己去做一些家里使用 的智设备.现在的中国不缺卖唱卖惨的,缺的是能动手创造一些能实际使用的而不是哗众取宠的人,天天喊着要反击外国技术封锁.那么我 ...

  5. proteus仿真micropython_【雕爷学编程】MicroPython动手做(04)——零基础学MaixPy之尝试运行...

    1.hello micropython #MicroPython动手做(04)--零基础学MaixPy之基本示例 #程序之一:hellomicropython #MicroPython动手做(04)- ...

  6. 不使用物理引擎,自己动手做真实物理的模拟投篮游戏

    最近打算做一个2D投篮游戏,由于对于BOX2D等物理引擎并不熟悉,加之一开始低估了游戏所需要的碰撞检测复杂度,认为仅仅涉及4面墙,篮球,篮板,篮筐,篮网的碰撞检测并不复杂.因此决定自己实现所需要的碰撞 ...

  7. python合成语音_MicroPython动手做(25)——语音合成与语音识别

    6.AB按键切换语言合成项目 [mw_shl_code=python,true]#MicroPython动手做(25)--语音合成与语音识别 #AB按键切换语言合成项目 from mpython im ...

  8. html语言可以干什么,JavaScript语言能做什么?

    JavaScript是除了HTML和CSS之外,万维网的核心技术之一.JavaScript支持交互式web页面,是web应用程序的重要组成部分.绝大多数网站都使用它,主要的网络浏览器都有专门的Java ...

  9. arduino 土壤温湿度传感器_【雕爷学编程】Arduino动手做(70)---土壤湿度传感器...

    37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的.鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为 ...

最新文章

  1. spring boot中的日志入门
  2. python正则表达式提取数字比较好_python正则表达式从字符串中提取数字的思路详解...
  3. Android背景色渐变效果(shape,gradient) (转)
  4. vue js 反编译_学会了Vue,前端面试却没找到工作?
  5. vs矩形框边框线显示被选中的区域;_Excel中,重复的数据高亮显示,如何快速删去?...
  6. ~~朴素dijkstra算法 (搜索与图论)(附模板题AcWing 849. Dijkstra求最短路 I)
  7. [leetcode] 5331. 跳跃游戏 V
  8. (转)金融从业人员的核心竞争力在哪里?
  9. jquery.treeview.js
  10. 部署Django REST Framework服务(Nginx + uWSGI + Django)
  11. R数据分析:用lme4包拟合线性和非线性混合效应模型
  12. 滴滴Booster移动APP质量优化框架 学习之旅
  13. 企业邮箱哪个最好用?企业邮箱域名怎么注册? 企业邮箱哪个安全?
  14. [渝粤教育] 中国地质大学 工业通风及除尘 复习题 (2)
  15. 计算机单总线结构的特点,单总线优缺点
  16. 山地自行车零件选择及使用误区
  17. 基于steam的游戏销量预测 — PART 1 — 爬取steam游戏相关数据的爬虫
  18. 关于在Python当中汉字日期的转换
  19. 武汉理工大学计算机考研排名2015,武汉理工大学和南京理工大学计算机研究生比较一下...
  20. 《趣学算法》欢迎来到异步社区!

热门文章

  1. wordpress-时光轴风格niconiconi极简清爽主题模板
  2. [生存志] 第76节 孔子读易大哉乾元
  3. navicat 手动设置索引unique,报错duplicate entry for key
  4. 设计模式【10】-- 顺便看看享元模式
  5. ubuntu 安装kde桌面_ubuntu安装kde桌面
  6. 产品运营怎么做规划?
  7. 谷歌创始人亲自下场改代码,ChatGPT让谷歌真慌了
  8. 最新异次元发卡系统源码荔枝发卡V3.0版
  9. 比亚迪李柯开发音频,比亚迪李柯开发声道
  10. 计算机联用测定无机盐溶解热测试题,实验一 计算机联用测定无机盐溶解热.doc...