有这样一个普通的日历需求

第一反应就是找插件,结果找到了,但是改起来非常麻烦,然后查下实现的原理,发现原来很简单,于是自己实现了一个。

首先分析一下这个组件,每页显示的是

当前月的所有日期及所占据的行剩下的格子所属的上一个月的最后几天或下一个月的前几天。

然后,神奇的Date类型原来可以这样获取日期实例:

new Date(2018,4,0)  // 2018年5月第一天的Date实例
new Date(2018,4,0) // 2018年4月最后一天的Date实例
new Date(2018,4,-1) // 2018年4月倒数第二天的Date实例
new Date(2018,4,32) // 2018年6月第一天的Date实例

所以,可以这样获取每一页的第一格的日期:

var monthFirstDate = new Date(2018, 4-1, 1) // 假设现在是四月
var monthFirstDay = monthFirstDate.getDay() // 本月第一天是星期几,星期日是0,星期一是1... // 所以如果每行第一个是星期日,则每一页的第一格的日期:
var pageFirstDate = new Date(2018, 4-1, 1-monthFirstDay)

而本页的下个月的日期的规律是

下个月第一个星期天之前的日期

所以,可以这样获取一页日历所有日期的Date实例

     /**
* @function getCalendarData
* @param {type} opts {
* day: 所在月的某一天的Date实例
* }
* @return {type} {当页所有日期的Date实例(数组)}
*/
function getCalendarData (opts) {
var opt = opts || {}
var _day = opt.day || new Date(), // Date实例,不传取今天
nowMonth = _day.getMonth(),
nowYear = _day.getFullYear(),
nowDate = _day.getDate() var firstDate = new Date(nowYear, nowMonth, 1), // 本月第一天
firstDay = firstDate.getDay(), // 本月第一天是星期几
activeNum = 1
var result = []
// 例: new Date(2018, 4, 0)结果是2018年3月31日,new Date(2018, 4, -1)结果是2018年3月30日
while (!(isNextMonth(_day, new Date(nowYear, nowMonth, activeNum - firstDay)) &&
new Date(nowYear, nowMonth, activeNum - firstDay).getDay() === 0)) {
// 非(当天是下个月的日期&&当天是周日),则推入数组
// 从new Date(nowYear, nowMonth, 1 - firstDay)开始是为了填上日历当前页里的上一个月的日期
result.push(new Date(nowYear, nowMonth, activeNum - firstDay))
activeNum++
}
function isNextMonth (a, b) { // a,b为Date实例
return (b.getFullYear() === a.getFullYear() && b.getMonth() === a.getMonth() + 1) || // 两个月在同一年
(b.getFullYear() === a.getFullYear() + 1 && b.getMonth() === 0 && a.getMonth() === 11) // 不在同一年
} return result
}

再之后,不管你用拼接html字符串还是用vue/react...,把上面的得出的Date实例数组循环一下,生成DOM,加上css,渲染出你想要的日历!

js实现日历的更多相关文章

  1. [JS,Canvas]日历时钟

    [JS,Canvas]日历时钟 Html: <!doctype html> <html> <head> <meta charset="UTF-8&q ...

  2. js简易日历

    js简易日历中设计的知识点:选项卡切换   数组    innerHTML  连接符 与选项卡的区别:div的个数不同 连接符中需要注意的:(优先级) "abc"+12+3+&qu ...

  3. JS输出日历

    页面HTML代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> &l ...

  4. 2.23 js处理日历控件(修改readonly属性)

    2.23 js处理日历控件(修改readonly属性) 前言    日历控件是web网站上经常会遇到的一个场景,有些输入框是可以直接输入日期的,有些不能,以我们经常抢票的12306网站为例,详细讲解如 ...

  5. 使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间。

    使用html+css+js实现日历与定时器,看看今天的日期和今天剩余的时间. 效果图: 哎,今天就又这么过去了,过的可真快 . 代码如下,复制即可使用: <!DOCTYPE html> & ...

  6. 用JS编写日历的简单思路

    提要:本文以写当前时间环境下当月的日历表为例,用最简单的方法实现JavaScript日历,旨在展示JS世界中实用为本.简单为上的解决问题的思路. Web页中的日历一般离不开表格,通常都使用表格装载指定 ...

  7. js中日历的代码

    Html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...

  8. JS实现日历控件选择后自动填充

    最近在做人事档案的项目,在做项目的初期对B/S这块不是很熟悉,感觉信心不是很强,随着和师哥同组人员的交流后发现,调试程序越来越好了,现在信心是倍增,只要自己自己踏实的去研究.理解代码慢慢的效果就出来了 ...

  9. 创建一个js日历(原生JS实现日历)

    前言 方法是有参考网上一些资料的,比如闰年的判断,比如每个月第一天是星期几的判断.不说太多,拆分出一个个函数,希望能描述尽可能的清晰明了. 一,判断闰年 //判断闰年 function runNian ...

  10. js 简单日历

    源地址:https://jingyan.baidu.com/article/546ae185fa4f721149f28cbf.htm 文件:index.htm <!DOCTYPE html> ...

随机推荐

  1. 前端面试题目汇总摘录(JS 基础篇 —— 2018.11.02更新)

    温故而知新,保持空杯心态 JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string type ...

  2. Tomcat配置SSL连接

    1.服务器端单项认证 在Tomcat的server.xml文件中,已经提供了现成的配置SSL连接器的代码,只要把<Connector>元素的注释去掉即可: <!—  Define a ...

  3. c/c++指针理解

    指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占 ...

  4. 1176: [Balkan2007]Mokia

    1176: [Balkan2007]Mokia 链接 分析 三维偏序问题,CDQ分治论文题. 代码 #include<bits/stdc++.h> using namespace std; ...

  5. guacamole实现剪切复制

    主要功能是实现把堡垒机的内容复制到浏览器端,把浏览器端的文本复制到堡垒机上. 借助一个中间的文本框,现将堡垒机内容复制到一个文本框,然后把文本框内容复制出来.或者将需要传递到堡垒机的内容先复制到文本框 ...

  6. java 判断上午/下午

    //结果为“0”是上午 结果为“1”是下午 public class GregorianTest { public static void main(String args[]) { Gregoria ...

  7. 「日常训练」Mike and Feet(Codeforces Round #305 Div. 2 D)

    题意 (Codeforces 548D) 对一个有$n$个数的数列,我们要求其连续$x(1\le x\le n)$(对于每个$x$,这样的连续group有若干个)的最小数的最大值. 分析 这是一道用了 ...

  8. 机器学习sklearn的快速使用--周振洋

    ML神器:sklearn的快速使用 传统的机器学习任务从开始到建模的一般流程是:获取数据 -> 数据预处理 -> 训练建模 -> 模型评估 -> 预测,分类.本文我们将依据传统 ...

  9. Week3 Teamework from Z.XML-团队分工及贡献分分配办法

    引言:团队项目即将开展,本文将就团队分工,以及分数分配办法进行阐述 一.团队分工 本周我们团队进行了初步的分工,结果如下: PM: 李孟 Dev:毛宇 薛亚杰 肖俊鹏 罗凡 Test:周敏轩 马辰 李 ...

  10. JavaSE复习(七)Stream流和方法引用

    Stream流 全新的Stream概念,用于解决已有集合类库既有的弊端. 传统集合的多步遍历代码 几乎所有的集合(如 Collection 接口或 Map 接口等)都支持直接或间接的遍历操作.而当我们 ...