首先我们想一下我们平常看到的日历选择器,通常头部会有一个星期几表头,下面就是日期,而日期下面通常会有1号,1号前面应该有一些上个月的日期,而最后一天后面还应该有下一个月的日期。

对于日期相关处理,JavaScript 提供了 Date 对象。

getDate 获得一个月的第几天

getDay 获得一个星期的第几天 (0 - 6)

getMonth 获取月份 (0 - 11)

getFullYear 获取年份

而对于比较 Date 对象的构造器有一个非常有意思的地方,那就是越界了之后,Date 会帮你自动校正日期。

new Date()

Sun Apr 16 2017 13:25:50 GMT+0800 (中国标准时间) // 当前日期 4/16

new Date(2017, 4, 1)

Mon May 01 2017 00:00:00 GMT+0800 (中国标准时间) // 日期 5/1 日

我们可以看到这里有一个陷阱,当我们给月份的参数是 4 的时候,其实它是五月份。

接下来我们来看一看日期的自动修正。

new Date(2017, 3, 0)

Fri Mar 31 2017 00:00:00 GMT+0800 (中国标准时间) // 3 月 31 日

// 4 月份的第 0 日,就是 3 月份的最后一日

new Date(2017, 3, 1)

Sat Apr 01 2017 00:00:00 GMT+0800 (中国标准时间) // 4 月 1 日

new Date(2017, 4, 0)

Sun Apr 30 2017 00:00:00 GMT+0800 (中国标准时间) // 4 月 30 日

// 5 月份的 0 日,就是 4 月份的最后一日

new Date(2017, 3, 31)

Mon May 01 2017 00:00:00 GMT+0800 (中国标准时间) // 5 月 1 日

4 月份只有 30 日, 当为 31 日的时候,变成了 5月份的 1 日

通过这些我们就可以获取当前月份的最后一天,以及上个月最后一天。

首先我们准备一个基本的静态页面

<

2017 - 3

>

一二三四五六日1234567

*{padding: 0;margin: 0;}

.field{

width: 300px;

margin: 20px auto;

font-size: 12px;

position: relative;

}

.field input{

width: 100%;

box-sizing: border-box;

outline: none;

}

.date-select{

background: #e8e8e8;

color: #fff;

cursor: pointer;

transition: all .8s;

position: absolute;

width: 100%;

z-index: 2;

display: none;

}

.date-select table{

width: 100%;

border-collapse: collapse;

text-align: center;

}

.date-select table caption:after{

content: '';

display: block;

clear: both;

}

.date-select table caption{

background: #999;

line-height: 20px;

}

.date-select table th{

background: #999;

}

.date-select table tr:first-child{

line-height: 30px;

}

.date-select table tr td{

border: 1px solid #f0f0f0;

}

.date-select table tr:not(:first-child){

line-height: 25px;

}

.date-select table caption span#prev-month{

float: left;

padding-left: 10px;

}

.date-select table caption span#next-month{

float: right;

padding-right: 10px;

}

const prevMonthBtn = document.querySelector('#prev-month'),

nextMonthBtn = document.querySelector('#next-month');

const dateInput = document.querySelector('#date-input');

const dateSelect = document.querySelector('.date-select');

dateInput.onclick = () => {

if(dateSelect.style.display == "block" ){

dateSelect.style.display = "none";

return;

}

dateSelect.style.display = "block";

}

prevMonthBtn.onclick = () => {

console.log("prev");

}

nextMonthBtn.onclick = () => {

console.log("next");

}

到目前为止,我们已经可以看到一个雏形了,但是这是有形无神的,现在我们再来准备我们的神魂精华,也就是获取日期的逻辑。

function get42ArrayDate(year, month){

// month 是正常月份

let now = year && month? new Date(year, month -1 ) : new Date();

let _year = now.getFullYear();

let _month = now.getMonth(); // Date 的月份比正常的月份小 1

let firstDayDateObj = new Date(_year, _month, 1); // 当月第一天日期

let _day = firstDayDateObj.getDay() == 0 ? 7 : firstDayDateObj.getDay(); // 修正一下星期的日期,当为 0 的时候说明为星期天

let needFillDayCount = _day - 1; // 我们需要补的日期, 当我们一号为星期天的时候,也就是 _date 为 7,则我们需要把星期一到星期六的天数给补完

let prevMonthLastDayDateObj = new Date(_year, _month, 0); // 上一个月最后一天的日期

let currentMonthLastDayDateObj = new Date(_year, _month + 1, 0); // 当前月最后一天的日期

let arr = Array.from({length:42}, (v, k) => k - needFillDayCount + 1 ) ; // 需要填充的数组 0 - 41 = 42 位 再加 1 是为了让 K 从 1开始

console.log(arr);

let ret_arrObj = arr.map((val, index) => {

// 现在我们对 负数日期,和超出限定的日期进行修正处理

// 我们留下这个负数和超出的是为了让其他地方也可以使用这些数据通过 Date 直接构造正确的日期

// 首先修正负数, 并且把正确的放在一个对象里面

let prevMonthLastDay = prevMonthLastDayDateObj.getDate(); // 上个月最后一天的日期

let currentMonthLastDay = currentMonthLastDayDateObj.getDate(); // 当前月最后一天

let ret_obj = {

index: val

};

if( val <= 0 ){

// 对负数日期进行修正

ret_obj.showDate = prevMonthLastDay + val; // 此时的 val 是一个负数,当 -0 的时候就是上月最后一天, - 1就是倒数第二天,以此类推。

ret_obj.showMonth = _month; // showMonth 顾名思义应该为我们所理解的月份,也就是从1开始的,而 _month 是从 0 开始的,所以我们应该 + 1, 而这里是上个月的,所以要 -1 所以刚好抵消

}else if (val > currentMonthLastDay){

// 对超出日期进行修正

ret_obj.showDate = val - currentMonthLastDay ; // 此时的 val 是超出正常日期的,我们让这个数减去单月的最后一天的值,相当于我们此时重新开始从 1 开始计数。 32 - 31 为 1号。 33 -31 为 2号, 以此类推。

ret_obj.showMonth = _month + 2;

}else{

// 正常的本月日期

ret_obj.showDate = val;

ret_obj.showMonth = _month + 1;

}

return ret_obj;

});

return {

currentMonth: _month + 1,

currentYear: _year,

dateArray: ret_arrObj

}

}

console.dir(get42ArrayDate());

解释都在注释里面,仔细看一下注释,然后自己运行一下,看看结果正确不正确。

接下来我们要把一些鼠标点击的事件,必须要等到已经渲染完HTML结构之后才能绑定,所以绑定的逻辑我们需要修改一下位置。

顺便我们把我们的渲染逻辑给写好,如下。

为了把当月的日期明显一点,我们增加一点样式

.date-select table tr td.current-month-day{

background: #d6d6d6;

}

function render(date){

let code = `

<

${date.currentYear} - ${date.currentMonth}

>

一二三四五六日

`;

date.dateArray.forEach((item, index) => {

if(index % 7 == 0) {

code += '

'

}

code += `

${item.showDate}`

});

dateSelect.innerHTML = code;

const prevMonthBtn = document.querySelector('#prev-month'),

nextMonthBtn = document.querySelector('#next-month');

prevMonthBtn.onclick = () => {

let month = date.currentMonth - 1;

let year = date.currentYear;

let prevMonthDate = get42ArrayDate(year, month);

render(prevMonthDate); // 重新渲染数据

}

nextMonthBtn.onclick = () => {

let month = date.currentMonth + 1;

let year = date.currentYear;

let nextMonthDate = get42ArrayDate(year, month);

render(nextMonthDate); // 重新渲染数据

}

dateSelect.addEventListener('click', (e) => {

let targetDom = e.target;

console.dir(targetDom)

if(targetDom.tagName == 'SPAN' || targetDom.tagName != 'TD') return;

let selectDay = new Date(date.currentYear, date.currentMonth - 1, targetDom.dataset.index); // currentMonth是正常月份所以要减一

const inputValue = selectDay.getFullYear() + " - " + (selectDay.getMonth() + 1) + " - " + selectDay.getDate();

dateInput.value = inputValue;

dateSelect.style.display = "none"; // 隐藏选择框

},false)

}

let date = get42ArrayDate();

render(date);

日历选择器html,日历选择器 - 常见 Web 特效实践相关推荐

  1. jq-weui滚动刷新,日历,和地址选择器

    最近工作方面的原因,接触到了微信公众号.然后网上找资料发现了jq-weui这个框架,觉得特别不错,分享一下 下载jq-weui点击这里下载jquery-weui,这里一定要注意下载的版本.因为有些功能 ...

  2. android 日历 时间选择,Android--DatePicker和TimePicker(日历选择器与时间选择器)

    一.DatePicker和TimePicker的两种监听器之OnDateChangedListener与OnTimeChangedListener 当用户更改了DatePicker(TimePicke ...

  3. 房子装修工程师CSS(一)之盒子模型/选择器的权重计算/常见样式属性/浮动float

    一.盒子模型 (一)CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:margin.border.padding.content(width.height). (二)盒子模型分两种: 1. ...

  4. Web前端第四季(jQuery):四:301-jQuery基本过滤器(奇数和偶数)+302-实现隔行换色+401-祖先选择器和子代选择器

    目录 一.目的 1.想:学习前端知识 2.想:记录笔记,下次不用看视频,直接看笔记就可以快速回忆. 二.参考 1.我自己代码的GitHub网址 2.SIKI学院:我参考此视频实操 3.w3school ...

  5. html5复合选择器,web前端练习31----Css,选择器(基本选择器,复合选择器,属性选择器,伪类,伪元素,优先级,雪碧图练习)...

    参考文档:https://man.ilovefishc.com/css3/ 一.基本选择器: 1通配符选择器 * 2元素选择器 element 3类选择器 .class 4id选择器 #id 5内联样 ...

  6. 顶级的 Bootstrap 日期选择器和时间选择器插件(附免费下载链接)

    顶级的 Bootstrap 日期选择器和时间选择器插件 Bootstrap的Datepicker元素是一种用户友好和直观的方式,可以轻松选择日期.它可用于移动端和PC端,还可以选择以 "从右 ...

  7. css类选择器与id选择器_一点点的类:有效地使用CSS类选择器

    css类选择器与id选择器 Classes are one of the most powerful CSS selectors, but they tend to be somewhat misun ...

  8. 选择器优先级_CSS选择器优先级指北

    来源:大前端FE(gh_f26dd6c6cfbf)欢迎大家一起来学习前端,期待你加入~ 相信大部分人刚开始写 css 的时候应该碰到过这样的问题. 明明只改了一行样式,然后整个页面就变成了这样↓   ...

  9. 同级选择器_基础选择器

    JavaScript中,获取元素用getElementById( ),getElementsByTagName( )等,这些方式都比较长和麻烦,但是在jQuery将会简单和简洁. 可以用jQuery选 ...

最新文章

  1. 《ASCE1885的源码分析》の跨平台互斥对象Mutex封装类
  2. HDLBits 系列(33)Sequence Recognition with Mealy FSM
  3. 029_jdbc-mysql二进制数据
  4. wxwidget编译安装_wxWidgets编译安装方法 | 学步园
  5. 深度学习在处理视频上几种主要技术方法
  6. Android获取所有Activity
  7. SUN:开源在Web2.0时代
  8. spring容器管理对象和new对象
  9. 伪随机算法c语言,伪随机算法实现各语言实现示例。
  10. 使用linux服务器实现路由器的功能(实验)
  11. asp毕业设计—— 基于asp+access的图书管理系统设计与实现(毕业论文+程序源码)——图书管理系统
  12. 【转】 GitHub 优秀的 Android 开源项目
  13. s5p6818 Smart6818 nanopi3开发板,uboot启动linux,配置nfs文件系统,设置bootargs
  14. 【从零开始学极狐gitlab】01环境搭建 #JIHULAB101
  15. Java实现PDF文件转图片(支持单页和多页)
  16. 总结——》【养生之道】
  17. IBM微码刷新(二)在服务器上使用BoMC介质刷新微码-cuixf@DC
  18. HLK-W801wifi连接
  19. socket广播报文收发简单梳理
  20. 软件安装管家公众号的部分链接

热门文章

  1. android系统文件误删,Dumpster:Android系统回收站 快速找回误删文件
  2. 奇梦达全面停产 启动破产程序
  3. 大卫·麦克里奇的Excel页面
  4. 设置custom debug keystore
  5. Thinkpad仅关闭-开启触摸板
  6. 11 《痛苦与狂喜:米开朗基罗传》-豆瓣评分8.9
  7. 亮点回顾!Go 11岁生快!
  8. 音视频开发系列(26)三种方式绘制图片-android开发
  9. 竹炭纤维集成墙面板装修的缺点是什么,有哪些弊端
  10. Debug Mac M1/M2 tensorflow:Could not find a version that satisfies the requirement tensorflow