介绍

用原生三件套从零到一实现以下日历模块,样式如图

目前具备以下功能

  1. 展示当前年月日,并对当前日其展示激活状态
  2. 点击上一月 下一月进行跳转

完成骨架搭建

首先先对,整体样式进行构思(对于毫无艺术细胞的我来说,差点要了半条命),最后决定先按照上图先做着,后边要改再说,日期内容采用的是表格进行渲染

    <div id="calendar"><div class="head"><div class="pre-month">上一月</div><div class="date"><!-- 这里先用的是死数据 --><div class="year">2022</div><div class="month">10月</div></div><div class="next-month">下一月</div></div><div class="main"><table><thead><tr><!-- 表格关于周几的就直接写上不生成了 --><td>日</td><td>一</td><td>二</td><td>三</td><td>四</td><td>五</td><td>六</td></tr></thead><tbody></tbody></table></div></div>

添加样式

样式就按照上面那个不太好看的样式来就行,因为是表格,所以布局的内容比较少

      #calendar {display: flex;flex-direction: column;width: 100vw;box-sizing: border-box;padding: 10px;margin: 26px auto;background-color: #f49bc4;}/* 标题部分 */#calendar .head {display: flex;width: 100%;margin-top: 10px;justify-content: space-evenly;font-size: 22px;font-weight: 700;color: #50508a90;}#calendar .head .pre-month,#calendar .head .next-month,#calendar .head .pre-month .year,#calendar .head .month {cursor: pointer;}/* 日期部分 */#calendar .main {width: 100%;color: aliceblue;font-size: 20px;font-weight: 900;margin-top: 20px;text-align: center;}#calendar .main table {width: 100%;color: #50508a90;}#calendar .main table tbody tr {width: 100%;}#calendar .main table tbody tr td {height: 36px;line-height: 36px;color: #fff;}.active {background-color: #50508a90;}

日期部分

这个练习案例,最主要的就是对于js内建对象Date的使用了

当前日期

首先我们需要拿到当前日期,然后一层一层的拿到以下内容:

  1. 今天星期几
  2. 当前月份有多少天
  3. 这个月的第一天是星期几
    获取当前日期是比较简单的
const date = new Date()
const year = date.getFullYear()  // 年份
const month = date.getMonth() + 1 // 月份
const weekDay = date.getDay() // 周几
const day = date.getDate() // 日期

后面在多个位置都需要根据日期获取这些数据,所以我把他抽成了一个函数,通过外界传入的日期对象获取对应的相关数据

function getDate(date) {const year = date.getFullYear() // 年份const month = date.getMonth() + 1 // 月份const weekDay = date.getDay() // 周几const day = date.getDate() // 日期return {year,month,weekDay,day,}
}

注意:Date对象的 getMonth()获取到的月数是从零开始的

获取本月的天数

获取当前月数的方法,我想半天没想到,后来查MDN(还是对原生Date对象的用法不太熟悉),找到了setDate方法,该方法根据本地时间来指定一个日期对象的天数,如果当我们传入的天数超出了该月的合理范围,它会根据一定规则进行更新对象

原时间对象会被改变

  1. 传入 0 :设置为上一个月的最后一天
  2. -1 :设置为上一个月的倒数第二天
  3. 32 :超出了当月的范围,往下一个月类推

根据上面的特点,所以我们可有下面的方法来获取某个月的天数

function getMonthDays(date) {// 将日期设置为32,表示自动计算为下个月的第几天(这取决于当前月份有多少天)let oldDate = new Date()date.setDate(32)let days = 32 - date.getDate()let dayArrs = []let i = 1while (i <= days) {dayArrs.push(oldDate.setDate(i))i++}// 返回当前月份的天数return {days,dayArrs,}
}

在这个方法中,不仅获取到了天数,也将每个日期对应的时间戳返回了

获取第一天的星期数

对于这个功能没有单独抽取方法,大概思路就是,使用setDate方法,将日期设置为1,然后getDay

// 这里使用 copyDate 是因为 setDate会改变源对象,影响了后面的操作,开始找半天没找到哪里不对
let firstDay = new Date(copyDate.setDate(1)).getDay()
收尾工作

编写一个renderDate函数用于渲染操作,同时也方便在其他方法中调用(如事件,初始化操作),这里用了表格,所以就根据日期的特点,采用的是6 x 7的表格,所以里边套了两层循环,在循环中获取了哪一个日期是当前活跃的

 function renderDate(date) {const copyDate = new Date(date) // 拷贝一份,防止后面一不小心改了tbody.innerHTML = "" // 清空之前的内容 Tconst { year, month, day } = getDate(date)// 获取当前的年月日const { dayArrs, days } = getCountDays(date)// 获取本月所有的时间戳, 以及本月的天数//#regioncurrentMonth = month // 记录状态currentYear = year // 记录状态//#endregion//#region  头部展示部分yearEl.innerHTML = yearmonthEl.innerHTML = month + "月"//#endregion// 用于统计当前已经渲染上的格子数let count = 0// 本月的第一天的星期数let firstDay = new Date(copyDate.setDate(1)).getDay()// 用于暂存创建的 tr 元素let trs = document.createDocumentFragment()for (let i = 0; i < 6; i++) {// 第一层循环代表行数let tr = document.createElement("tr")// 用于暂存创建的 td 元素let tds = document.createDocumentFragment()for (let j = 0; j < 7; j++) {// 这一层表示列数let td = document.createElement("td")// 当前日期的星期数let day = new Date(dayArrs[count]).getDay()if (i === 0 && j < firstDay) {// 这里的判断用于跳过 1 号之前的日期格子tds.append(td)continue}if (count < days) {// 如果以渲染的格子数小于天数就继续添加if (new Date(dayArrs[count]).getDate() === new Date().getDate()) {// 将当前日期设置为激活状态td.classList.add("active")}td.innerHTML = new Date(dayArrs[count]).getDate()}tds.append(td)count++}tr.append(tds)trs.append(tr)}tbody.append(trs)}

完成该函数之后,我们通过一个IIFE进行初始化操作

(function () {let date = new Date() // 获取当前日期renderDate(date)})()

结束语

到这里,具有基本功能的日历差不多就实现了,虽然功能比较简单,但是我还是花了好长时间完成,不过也算是对Date熟悉了些了,这波不亏!后续完成更加复杂的功能

简单的日历组件

前端练手案例之日历(原生)一相关推荐

  1. 2022最新版40个前端练手项目【附视频+源码】

    不管学习哪门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦, 不用多 说,大家都知道学编程语言一定要做项目才行. 本次给到大家的是40个前端实战练手项目(附源码和视频讲解),希望对大家有一 ...

  2. 新手前端练手网站_程序员从入门到入狱:必收藏的七大网站

    作为一个正在自学JAVA的菜鸡,我把我在学习中用到的网站整理了一下,分享给和我一样正在学习编程的小白们. 1.菜鸟教程 菜鸟教程是零基础小白入门的一个必备网站,菜鸟教程包含了所有跟编程有关的技术.从前 ...

  3. 新手前端练手网站_影视后期新手大礼包

    点击上方蓝色字关注我们~ 为什么很多人学习影视后期学不下去?为什么很多人学习影视后期不知道是为了什么?无论是工作需要,或者兴趣爱好,又或者转行设计.还在迷茫的你,请认真看完下面的视频,会对你有十分大的 ...

  4. 5个前端练手项目(html css js canvas)

    前言: 首先祝大家端午节快乐.本篇文章有5个练手项目 对于刚学完前端三剑客的你们.应该是一个很好的实践 目录

  5. 新手前端练手网站_编程到底难不难学?新手入门选择哪种语言好?

    以下内容适合的读者:想要学习编程的小白 一.编程到底难不难学? 对于这个问题我的回答是不知道,学会了编程的人会说好学,中途就放弃的人会说很难,任何知识想要掌握好都不是一件容易的事情.所以我决定用自己的 ...

  6. Vue介绍以及练手案例——音乐播放器(搜索音乐、听歌、看评论、看mv等)(持续更新)

    Vue概述 它是一种 javascript框架 可以简化DOM操作 进行响应式数据驱动 el: 挂载点 vue实例的作用范围:vue会管理 el 选项所命中的元素及其内部的后代元素. 可以使用其他选择 ...

  7. 自学web前端练手——js的考试倒计时

    考试倒计时,并附带15分钟和5分钟的图片更换.(没调整统一的图片大小) 起初文本一直出不来,搞了半小时(一条一条的检查排查错误),最后把setInterval从函数体中弄出来就好了,吐了_(:з」∠) ...

  8. 前端练手项目 HTML 游戏叠高塔(包含源码)

    叠高塔游戏通过点击[屏幕]或按[空格键]来放置积木. 这个游戏的灵感来源于iPhone上的游戏 Stack: https://itunes.apple.com/us/app/stack/id10804 ...

  9. web前端练手小项目——仿照小米商城

    大部分是静态页面,使用的js知识只有一点点 实现的效果: 实现的html代码: <!DOCTYPE html> <html lang="en"> <h ...

最新文章

  1. 一个查看全部用户的磁盘空间使用情况的脚本
  2. 【转】秒杀系统架构分析与实战
  3. linux闹钟软件下载,电量充满警示闹铃
  4. RTP/RTCP中的Jitter
  5. 关于数组表示的二叉结构中,下标乘除法对应关系的理解
  6. 从代码到300优质客户,用户画像在销售的实战应用
  7. Thinkphp报错:fields not exists:[status]
  8. System Exception:故障解决:端口已被占用 1080--->的处理方法
  9. 我的爷爷(知识渊博的下乡知青)
  10. 从《三体》中的“降维打击”看网络世界,论维度升级的方法与实践
  11. 图像表头数据读取,图像数据块读取,图像类型转换
  12. bootstrap登录模板
  13. c语言获奖程序,1987年国际C语言混乱代码大赛获奖的一行代码
  14. bluez——mgmt分析
  15. 如何为你的网站添加标志性的图标(头像)呢?
  16. 安全单点登录(SSO)解决方案
  17. Zoom and pan, introduction to FabricJS part 5(缩放和平移,介绍Fabric.js第五部分)
  18. 治安防控平台搭建,为您打造平安社区
  19. 9岁有赞:新零售业务快速增长 推新品牌扶持计划
  20. 浅析企业私有云中的存储架构

热门文章

  1. 用python编写文本进度条
  2. PDF文件怎么转换为图片?
  3. 日常学习记录——tkinter显示excel表格中的数据
  4. jdk下载与安装教程(win10)
  5. mysql查询排除字段_mysql查询表,指定排除字段
  6. springboot1:项目启动
  7. 二进制数转换十进制数(十进制转二进制)
  8. 两个月能学什么?零基础小白全网热门预训练模型梳理整合
  9. 设计到生产:流程名词解释
  10. python实现给pdf文件加骑缝章效果